DFBResult dfb_x11_image_destroy_handler( DFBX11 *x11, x11Image *image ) { D_MAGIC_ASSERT( image, x11Image ); XLockDisplay( x11->display ); XFreeGC( x11->display, image->gc ); XFreePixmap( x11->display, image->pixmap ); XShmDetach( x11->display, &image->seginfo ); XDestroyImage( image->ximage ); XUnlockDisplay( x11->display ); shmdt( image->seginfo.shmaddr ); shmctl( image->seginfo.shmid, IPC_RMID, NULL ); return DFB_OK; }
DFBResult dfb_x11_destroy_window_handler( DFBX11 *x11 ) { DFBX11Shared *shared = x11->shared; D_DEBUG_AT( X11_Window, "%s()\n", __FUNCTION__ ); XLockDisplay( x11->display ); if (shared->xw) { XWindow *xw = shared->xw; shared->xw = NULL; dfb_x11_close_window( x11, xw ); } XSync( x11->display, False ); XUnlockDisplay( x11->display ); return DFB_OK; }
void overview(const char *arg) { XDefineCursor(dpy,win,None); XLockDisplay(dpy); /* incase render thread is still working */ XCopyArea(dpy,sorter.view,win,gc,0,0,sw,sh,0,0); XUnlockDisplay(dpy); /* calculate coordinates for highlighter box */ int i, n = 0, x = (sw-sorter.grid*(sorter.w+10))/2, y = 10; for (i = 0; i < show.num; i++) { x += sorter.w + 10; if (++n == sorter.grid) { n = 0; x = (sw-sorter.grid*(sorter.w+10))/2; y += sorter.h + 10; } } /* draw the highlighter box */ XDrawRectangle(dpy,win,hgc,x-1,y-1,sorter.w+2,sorter.h+2); XFlush(dpy); if (presenter_mode) fprintf(stdout,"SLIDER: %d current=%lu, next=%lu\n", show.num,win,show.slide[show.num]); fflush(stdout); overview_mode = True; }
XVWindow::~XVWindow() { unsigned int i = 0; XLockDisplay (_display); #ifdef HAVE_SHM if (_useShm) { for (i = 0; i < NUM_BUFFERS; i++) if (_isInitialized && _XShmInfo[i].shmaddr) { XShmDetach (_display, &_XShmInfo[i]); shmdt (_XShmInfo[i].shmaddr); } } else #endif { for (i = 0; i < NUM_BUFFERS; i++) if ((_XVImage[i]) && (_XVImage[i]->data)) { free (_XVImage[i]->data); _XVImage[i]->data = NULL; } } for (i = 0; i < NUM_BUFFERS; i++) if (_XVImage[i]) { XFree (_XVImage[i]); _XVImage[i] = NULL; } if (_XVPort) { XvUngrabPort (_display, _XVPort, CurrentTime); grabbedPorts.erase(_XVPort); _XVPort = 0; } XUnlockDisplay(_display); }
void fillpoly (int numpoints, int *polypoints) { int i; XPoint *Points; Points = malloc (numpoints * sizeof (XPoint)); if (Points == NULL) { TcGraphResult = grNoScanMem; return; } // Convert to viewport coordinates. for (i = 0; i < numpoints; i++) { Points[i].x = TcViewLeft + *polypoints++; Points[i].y = TcViewTop + *polypoints++; } // Now do the actual drawing. XLockDisplay (TcDisplay); XSetFillStyle (TcDisplay, TcGc, FillTiled); XSetTile (TcDisplay, TcGc, TcTile); XFillPolygon (TcDisplay, TcPixmaps[TcActivePage], TcGc, Points, numpoints, Complex, CoordModeOrigin); XDrawLines (TcDisplay, TcPixmaps[TcActivePage], TcGc, Points, numpoints, CoordModeOrigin); if (TcActivePage == TcVisualPage) { XFillPolygon (TcDisplay, TcWindow, TcGc, Points, numpoints, Complex, CoordModeOrigin); XDrawLines (TcDisplay, TcWindow, TcGc, Points, numpoints, CoordModeOrigin); XSync (TcDisplay, False); } XSetFillStyle (TcDisplay, TcGc, FillSolid); XUnlockDisplay (TcDisplay); free (Points); }
void sendEvent ( Display * pdisplay, Window hwindow, const char * pszId ) { Display * pdisplayTmp = NULL; XClientMessageEvent xmsgevent; if (! pdisplay) { pdisplay = pdisplayTmp = XOpenDisplay(NULL); } xmsgevent.type = ClientMessage; xmsgevent.display = pdisplay; xmsgevent.window = pparentinfo_->hwindow; xmsgevent.message_type = XInternAtom(xmsgevent.display, pszId, False ); xmsgevent.format = 32; XLockDisplay(pdisplay); XSendEvent(xmsgevent.display, xmsgevent.window, 0, NoEventMask, (XEvent *) & xmsgevent ); XUnlockDisplay(pdisplay); if (pdisplayTmp) { XCloseDisplay(pdisplayTmp); } }
void MMSFB::realignLayer() { #ifdef __HAVE_XLIB__ static bool first = true; if(first==false) return; first=false; for(int i=0; ;i++) { if(mmsfb->x_windows[i]==0) break; else if(mmsfb->x_windows[i]!=mmsfb->input_window) { XLockDisplay(mmsfb->x_display); XLowerWindow(mmsfb->x_display, mmsfb->x_windows[i]); XFlush(mmsfb->x_display); XSync(mmsfb->x_display,False); X11_IMPL *impl = (X11_IMPL *)mmsfb->layer[i]->getImplementation(); XPutImage(mmsfb->x_display, mmsfb->x_windows[i], impl->x_gc, mmsfb->rootimage, 0,0, 0, 0, mmsfb->display_w, mmsfb->display_h); //XUnmapWindow(mmsfb->x_display, mmsfb->x_windows[i]); //printf("unmapping layer %d\n", i); XSync(mmsfb->x_display,False); XMapWindow(mmsfb->x_display, mmsfb->x_windows[i]); XRaiseWindow(mmsfb->x_display, mmsfb->input_window); //printf("mapping layer %d\n", i); XFlush(mmsfb->x_display); XSync(mmsfb->x_display,False); XUnlockDisplay(mmsfb->x_display); } } #endif }
void XCompcapMain::tick(float seconds) { if (!obs_source_showing(p->source)) return; PLock lock(&p->lock, true); if (!lock.isLocked()) return; XCompcap::processEvents(); if (p->win && XCompcap::windowWasReconfigured(p->win)) { p->window_check_time = FIND_WINDOW_INTERVAL; p->win = 0; } XDisplayLock xlock; XWindowAttributes attr; if (!p->win || !XGetWindowAttributes(xdisp, p->win, &attr)) { p->window_check_time += (double)seconds; if (p->window_check_time < FIND_WINDOW_INTERVAL) return; Window newWin = getWindowFromString(p->windowName); p->window_check_time = 0.0; if (newWin && XGetWindowAttributes(xdisp, newWin, &attr)) { p->win = newWin; updateSettings(0); } else { return; } } if (!p->tex || !p->gltex) return; obs_enter_graphics(); if (p->lockX) { XLockDisplay(xdisp); XSync(xdisp, 0); } if (p->include_border) { gs_copy_texture_region( p->tex, 0, 0, p->gltex, p->cur_cut_left, p->cur_cut_top, width(), height()); } else { gs_copy_texture_region( p->tex, 0, 0, p->gltex, p->cur_cut_left + p->border, p->cur_cut_top + p->border, width(), height()); } if (p->cursor && p->show_cursor) { xcursor_tick(p->cursor); p->cursor_outside = p->cursor->x < p->cur_cut_left || p->cursor->y < p->cur_cut_top || p->cursor->x > int(p->width - p->cur_cut_right) || p->cursor->y > int(p->height - p->cur_cut_bot); } if (p->lockX) XUnlockDisplay(xdisp); obs_leave_graphics(); }
int fbx_init(fbx_struct *fb, fbx_wh wh, int width_, int height_, int useShm) { int width, height; int rmask, gmask, bmask, ps, i; #ifdef _WIN32 BMINFO bminfo; HBITMAP hmembmp=0; RECT rect; HDC hdc=NULL; #else XWindowAttributes xwa; int shmok=1, alphaFirst, pixmap=0; #endif if(!fb) _throw("Invalid argument"); #ifdef _WIN32 if(!wh) _throw("Invalid argument"); _w32(GetClientRect(wh, &rect)); if(width_>0) width=width_; else { width=rect.right-rect.left; if(width<=0) width=MINWIDTH; } if(height_>0) height=height_; else { height=rect.bottom-rect.top; if(height<=0) height=MINHEIGHT; } if(fb->wh==wh) { if(width==fb->width && height==fb->height && fb->hmdc && fb->hdib && fb->bits) return 0; else if(fbx_term(fb)==-1) return -1; } memset(fb, 0, sizeof(fbx_struct)); fb->wh=wh; _w32(hdc=GetDC(fb->wh)); _w32(fb->hmdc=CreateCompatibleDC(hdc)); _w32(hmembmp=CreateCompatibleBitmap(hdc, width, height)); _w32(GetDeviceCaps(hdc, RASTERCAPS)&RC_BITBLT); _w32(GetDeviceCaps(fb->hmdc, RASTERCAPS)&RC_DI_BITMAP); bminfo.bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bminfo.bmi.bmiHeader.biBitCount=0; _w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS)); _w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS)); _w32(DeleteObject(hmembmp)); hmembmp=0; /* (we only needed it to get the screen properties) */ ps=bminfo.bmi.bmiHeader.biBitCount/8; if(width>0) bminfo.bmi.bmiHeader.biWidth=width; if(height>0) bminfo.bmi.bmiHeader.biHeight=height; fb->width=bminfo.bmi.bmiHeader.biWidth; fb->height=bminfo.bmi.bmiHeader.biHeight; if(ps<3) { /* Make the buffer BGRA */ bminfo.bmi.bmiHeader.biCompression=BI_BITFIELDS; bminfo.bmi.bmiHeader.biBitCount=32; ps=4; (*(DWORD *)&bminfo.bmi.bmiColors[0])=0xFF0000; (*(DWORD *)&bminfo.bmi.bmiColors[1])=0xFF00; (*(DWORD *)&bminfo.bmi.bmiColors[2])=0xFF; } fb->pitch=BMPPAD(fb->width*ps); /* Windoze bitmaps are always padded */ if(bminfo.bmi.bmiHeader.biCompression==BI_BITFIELDS) { rmask=(*(DWORD *)&bminfo.bmi.bmiColors[0]); gmask=(*(DWORD *)&bminfo.bmi.bmiColors[1]); bmask=(*(DWORD *)&bminfo.bmi.bmiColors[2]); } else { rmask=0xFF0000; gmask=0xFF00; bmask=0xFF; } fb->format=-1; for(i=0; i<FBX_FORMATS; i++) if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i] && ps==fbx_ps[i] && fbx_alphafirst[i]==0) fb->format=i; if(fb->format==-1) _throw("Display has unsupported pixel format"); bminfo.bmi.bmiHeader.biHeight=-bminfo.bmi.bmiHeader.biHeight; /* (our convention is top-down) */ _w32(fb->hdib=CreateDIBSection(hdc, &bminfo.bmi, DIB_RGB_COLORS, (void **)&fb->bits, NULL, 0)); _w32(SelectObject(fb->hmdc, fb->hdib)); ReleaseDC(fb->wh, hdc); return 0; finally: if(hmembmp) DeleteObject(hmembmp); if(hdc) ReleaseDC(fb->wh, hdc); #else if(!wh.dpy || !wh.d) _throw("Invalid argument"); if(wh.v) { _x11(XGetGeometry(wh.dpy, wh.d, &xwa.root, &xwa.x, &xwa.y, (unsigned int *)&xwa.width, (unsigned int *)&xwa.height, (unsigned int *)&xwa.border_width, (unsigned int *)&xwa.depth)); xwa.visual=wh.v; useShm=0; pixmap=1; } else { _x11(XGetWindowAttributes(wh.dpy, wh.d, &xwa)); } if(width_>0) width=width_; else width=xwa.width; if(height_>0) height=height_; else height=xwa.height; if(fb->wh.dpy==wh.dpy && fb->wh.d==wh.d) { if(width==fb->width && height==fb->height && fb->xi && fb->xgc && fb->bits) return 0; else if(fbx_term(fb)==-1) return -1; } memset(fb, 0, sizeof(fbx_struct)); fb->wh.dpy=wh.dpy; fb->wh.d=wh.d; #ifdef USESHM if(!useShm) { static int alreadyWarned=0; if(!alreadyWarned && warningFile) { fprintf(warningFile, "[FBX] Disabling shared memory blitting\n"); alreadyWarned=1; } } if(useShm && XShmQueryExtension(fb->wh.dpy)) { static int alreadyWarned=0; fb->shminfo.shmid=-1; if(!(fb->xi=XShmCreateImage(fb->wh.dpy, xwa.visual, xwa.depth, ZPixmap, NULL, &fb->shminfo, width, height))) { useShm=0; goto noshm; } if((fb->shminfo.shmid=shmget(IPC_PRIVATE, fb->xi->bytes_per_line*fb->xi->height+1, IPC_CREAT|0777))==-1) { useShm=0; XDestroyImage(fb->xi); goto noshm; } if((fb->shminfo.shmaddr=fb->xi->data =(char *)shmat(fb->shminfo.shmid, 0, 0))==(char *)-1) { useShm=0; XDestroyImage(fb->xi); shmctl(fb->shminfo.shmid, IPC_RMID, 0); goto noshm; } fb->shminfo.readOnly=False; XLockDisplay(fb->wh.dpy); XSync(fb->wh.dpy, False); prevHandler=XSetErrorHandler(xhandler); extok=1; serial=NextRequest(fb->wh.dpy); XShmAttach(fb->wh.dpy, &fb->shminfo); XSync(fb->wh.dpy, False); XSetErrorHandler(prevHandler); shmok=extok; if(!alreadyWarned && !shmok && warningFile) { fprintf(warningFile, "[FBX] WARNING: MIT-SHM extension failed to initialize (this is normal on a\n"); fprintf(warningFile, "[FBX] remote connection.) Will use X Pixmap drawing instead.\n"); alreadyWarned=1; } XUnlockDisplay(fb->wh.dpy); if(shmok) { char *env=getenv("FBX_USESHMPIXMAPS"); if(env && !strcmp(env, "1")) { static int alreadyWarned=0; if(!alreadyWarned && warningFile) { fprintf(warningFile, "[FBX] Using MIT-SHM pixmaps\n"); alreadyWarned=1; } fb->pm=XShmCreatePixmap(fb->wh.dpy, fb->wh.d, fb->shminfo.shmaddr, &fb->shminfo, width, height, xwa.depth); if(!fb->pm) shmok=0; } } shmctl(fb->shminfo.shmid, IPC_RMID, 0); if(!shmok) { useShm=0; XDestroyImage(fb->xi); shmdt(fb->shminfo.shmaddr); shmctl(fb->shminfo.shmid, IPC_RMID, 0); goto noshm; } fb->xattach=1; fb->shm=1; } else if(useShm) { static int alreadyWarned=0; if(!alreadyWarned && warningFile) { fprintf(warningFile, "[FBX] WARNING: MIT-SHM extension not available. Will use X pixmap\n"); fprintf(warningFile, "[FBX] drawing instead.\n"); alreadyWarned=1; } useShm=0; } noshm: if(!useShm) #endif { if(!pixmap) _x11(fb->pm=XCreatePixmap(fb->wh.dpy, fb->wh.d, width, height, xwa.depth)); _x11(fb->xi=XCreateImage(fb->wh.dpy, xwa.visual, xwa.depth, ZPixmap, 0, NULL, width, height, 8, 0)); if((fb->xi->data=(char *)malloc(fb->xi->bytes_per_line*fb->xi->height+1)) ==NULL) _throw("Memory allocation error"); } ps=fb->xi->bits_per_pixel/8; fb->width=fb->xi->width; fb->height=fb->xi->height; fb->pitch=fb->xi->bytes_per_line; if(fb->width!=width || fb->height!=height) _throw("Bitmap returned does not match requested size"); rmask=fb->xi->red_mask; gmask=fb->xi->green_mask; bmask=fb->xi->blue_mask; alphaFirst=0; if(fb->xi->byte_order==MSBFirst) { if(ps<4) { rmask=fb->xi->blue_mask; gmask=fb->xi->green_mask; bmask=fb->xi->red_mask; } else alphaFirst=1; } fb->format=-1; for(i=0; i<FBX_FORMATS; i++) if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i] && ps==fbx_ps[i] && fbx_alphafirst[i]==alphaFirst) fb->format=i; if(fb->format==-1) _throw("Display has unsupported pixel format"); fb->bits=fb->xi->data; fb->pixmap=pixmap; _x11(fb->xgc=XCreateGC(fb->wh.dpy, fb->pm? fb->pm:fb->wh.d, 0, NULL)); return 0; finally: #endif fbx_term(fb); return -1; }
static DFBResult x11AllocateKey( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, const char *key, u64 handle, CoreSurfaceAllocation *allocation, void *alloc_data ) { CoreSurface *surface; x11AllocationData *alloc = alloc_data; x11PoolLocalData *local = pool_local; DFBX11 *x11 = local->x11; D_DEBUG_AT( X11_Surfaces, "%s( %s, 0x%08llx )\n", __FUNCTION__, key, (unsigned long long) handle ); D_DEBUG_AT( X11_Surfaces, " -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if (!strcmp( key, "Pixmap/X11" )) { D_DEBUG_AT( X11_Surfaces, " -> Pixmap/X11\n" ); alloc->type = X11_ALLOC_PIXMAP; } else if (!strcmp( key, "Window/X11" )) { D_DEBUG_AT( X11_Surfaces, " -> Window/X11\n" ); alloc->type = X11_ALLOC_WINDOW; } else { D_BUG( "unexpected key '%s'", key ); return DFB_BUG; } dfb_surface_calc_buffer_size( surface, 8, 8, &alloc->pitch, &allocation->size ); // alloc->depth = DefaultDepthOfScreen( x11->screenptr ); // alloc->visual = DefaultVisualOfScreen( x11->screenptr ); alloc->visual = x11->visuals[DFB_PIXELFORMAT_INDEX(buffer->format)]; alloc->depth = DFB_COLOR_BITS_PER_PIXEL( buffer->format ) + DFB_ALPHA_BITS_PER_PIXEL( buffer->format ); if (alloc->depth == DefaultDepthOfScreen( x11->screenptr )) alloc->visual = DefaultVisualOfScreen( x11->screenptr ); D_DEBUG_AT( X11_Surfaces, " -> visual %p (id %lu), depth %d\n", alloc->visual, alloc->visual->visualid, alloc->depth ); if (handle) { switch (alloc->type) { case X11_ALLOC_PIXMAP: XLockDisplay( x11->display ); alloc->xid = (unsigned long) handle; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: Import Pixmap 0x%08lx\n", alloc->xid ); break; case X11_ALLOC_WINDOW: { XLockDisplay( x11->display ); alloc->window = (unsigned long) handle; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> window 0x%08lx\n", (long) alloc->window ); XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> redirected\n" ); alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window ); // alloc->xid = alloc->window; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnmapWindow( x11->display, alloc->window ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> unmapped\n" ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: Import Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid ); break; } default: D_BUG( "unexpected allocation type %d\n", alloc->type ); return DFB_BUG; } } else { // alloc->type = X11_ALLOC_PIXMAP; switch (alloc->type) { case X11_ALLOC_PIXMAP: XLockDisplay( x11->display ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> creating pixmap...\n" ); alloc->xid = XCreatePixmap( x11->display, DefaultRootWindow(x11->display), allocation->config.size.w, allocation->config.size.h, alloc->depth ); x11->Sync( x11 ); XSync( x11->display, False ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: New Pixmap 0x%08lx\n", alloc->xid ); alloc->created = true; break; case X11_ALLOC_WINDOW: { Window w = (Window) (long) buffer->surface->data; XSetWindowAttributes attr; attr.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | ExposureMask | StructureNotifyMask; attr.background_pixmap = 0; XLockDisplay( x11->display ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> creating window...\n" ); alloc->window = w?:XCreateWindow( x11->display, DefaultRootWindow(x11->display), 600, 200, allocation->config.size.w, allocation->config.size.h, 0, alloc->depth, InputOutput, alloc->visual, CWEventMask, &attr ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> window 0x%08lx\n", (long) alloc->window ); buffer->surface->data = (void*) (long) alloc->window; XMapRaised( x11->display, alloc->window ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> raised\n" ); XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> redirected\n" ); alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window ); // alloc->xid = alloc->window; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnmapWindow( x11->display, alloc->window ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> unmapped\n" ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: New Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid ); alloc->created = !w; break; } default: D_BUG( "unexpected allocation type %d\n", alloc->type ); return DFB_BUG; } } alloc->gc = XCreateGC( x11->display, alloc->xid, 0, NULL ); allocation->offset = alloc->type; return DFB_OK; }
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem) { int count; int status; int x, y; int width, height; XImage* image; rdpShadowScreen* screen; rdpShadowServer* server; rdpShadowSurface* surface; RECTANGLE_16 invalidRect; RECTANGLE_16 surfaceRect; const RECTANGLE_16 *extents; server = subsystem->server; surface = server->surface; screen = server->screen; count = ArrayList_Count(server->clients); if (count < 1) return 1; surfaceRect.left = 0; surfaceRect.top = 0; surfaceRect.right = surface->width; surfaceRect.bottom = surface->height; XLockDisplay(subsystem->display); /* * Ignore BadMatch error during image capture. The screen size may be * changed outside. We will resize to correct resolution at next frame */ XSetErrorHandler(x11_shadow_error_handler_for_capture); if (subsystem->use_xshm) { image = subsystem->fb_image; XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0); status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect); } else { image = XGetImage(subsystem->display, subsystem->root_window, surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap); if (!image) { /* * BadMatch error happened. The size may have been changed again. * Give up this frame and we will resize again in next frame */ goto fail_capture; } status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) image->data, image->bytes_per_line, &invalidRect); } /* Restore the default error handler */ XSetErrorHandler(NULL); XSync(subsystem->display, False); XUnlockDisplay(subsystem->display); region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect); if (!region16_is_empty(&(surface->invalidRegion))) { extents = region16_extents(&(surface->invalidRegion)); x = extents->left; y = extents->top; width = extents->right - extents->left; height = extents->bottom - extents->top; freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, x, y, width, height, (BYTE*) image->data, PIXEL_FORMAT_XRGB32, image->bytes_per_line, x, y, NULL); //x11_shadow_blend_cursor(subsystem); count = ArrayList_Count(server->clients); shadow_subsystem_frame_update((rdpShadowSubsystem *)subsystem); if (count == 1) { rdpShadowClient* client; client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0); if (client) { subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder); } } region16_clear(&(surface->invalidRegion)); } if (!subsystem->use_xshm) XDestroyImage(image); return 1; fail_capture: XSetErrorHandler(NULL); XSync(subsystem->display, False); XUnlockDisplay(subsystem->display); return 0; }
void XWindow::ToggleFullscreen () { if (_embedded) return; Window childWindow; XWindowAttributes xwattributes; int newX = 0; int newY = 0; int newWidth = 0; int newHeight = 0; if (_state.fullscreen) { // not needed with EWMH fs if (!(_wmType & wm_FULLSCREEN)) { newX = _state.oldx; newY = _state.oldy; newWidth = _state.oldWidth; newHeight = _state.oldHeight; SetDecoration (true); } // removes fullscreen state if wm supports EWMH SetEWMHFullscreen (_NET_WM_STATE_REMOVE); } else { // sets fullscreen state if wm supports EWMH SetEWMHFullscreen (_NET_WM_STATE_ADD); // not needed with EWMH fs - save window coordinates/size // and discover fullscreen window size if (!(_wmType & wm_FULLSCREEN)) { XLockDisplay (_display); newX = 0; newY = 0; newWidth = DisplayWidth (_display, DefaultScreen (_display)); newHeight = DisplayHeight (_display, DefaultScreen (_display)); SetDecoration (false); XFlush (_display); XTranslateCoordinates (_display, _XWindow, RootWindow (_display, DefaultScreen (_display)), 0, 0, &_state.oldx, &_state.oldy, &childWindow); XGetWindowAttributes (_display, _XWindow, &xwattributes); XUnlockDisplay (_display); _state.oldWidth = xwattributes.width; _state.oldHeight = xwattributes.height; } } // not needed with EWMH fs - create a screen-filling window on top // and turn of decorations if (!(_wmType & wm_FULLSCREEN)) { SetSizeHints (newX, newY, _XImage->width, _XImage->height, newWidth, newHeight); XLockDisplay (_display); SetLayer (!_state.fullscreen ? 0 : 1); XMoveResizeWindow (_display, _XWindow, newX, newY, newWidth, newHeight); XUnlockDisplay (_display); } // some WMs lose ontop after fullscreeen if (_state.fullscreen & _state.ontop) SetLayer (1); XLockDisplay (_display); XMapRaised (_display, _XWindow); XRaiseWindow (_display, _XWindow); XSync (_display, False); XUnlockDisplay (_display); _state.fullscreen = !_state.fullscreen; }
int XWindow::Init (Display* dp, Window rootWindow, GC gc, int x, int y, int windowWidth, int windowHeight, int imageWidth, int imageHeight) { _display = dp; _rootWindow = rootWindow; _imageWidth = imageWidth; _imageHeight = imageHeight; PTRACE(4, "X11\tInitiasing new X11 window with " << windowWidth << "x" << windowHeight << " at " << x << "," << y); XLockDisplay (_display); #if PTRACING DumpVisuals(); #endif if (!CreateAtomsAndWindow(gc, x, y, windowWidth, windowHeight)) { XUnlockDisplay(_display); return 0; } CreateXImage(windowWidth, windowHeight); _isInitialized = true; XUnlockDisplay (_display); // check if that format is supported struct xFormatsentry* xFormat = xFormats; while (xFormat->name) { if (xFormat->depth == _XImage->bits_per_pixel && xFormat->byte_order == _XImage->byte_order && xFormat->red_mask == _XImage->red_mask && xFormat->green_mask == _XImage->green_mask && xFormat->blue_mask == _XImage->blue_mask) break; xFormat++; } PTRACE(4, "X11\tXImage created with format: " << _XImage->bits_per_pixel <<" BPP, " << "Byte order: " << (_XImage->byte_order ? "MSBFirst" : "LSBFirst") << " Native: " << (BO_NATIVE ? "MSBFirst" : "LSBFirst")); PTRACE(4, std::hex << "X11\tMask: Red: 0x" << _XImage->red_mask << " Green: 0x" << _XImage->green_mask << " Blue: 0x" << _XImage->blue_mask << std::dec); if (!xFormat->name) { PTRACE(1, "X11\tX server image format not supported, please contact the developers"); return 0; } snprintf (_colorFormat, sizeof(_colorFormat), "%s", xFormat->name); _outOffset = 0; _planes = xFormat->planes; #ifdef WORDS_BIGENDIAN if (g_strcmp0 (xFormat->name, "BGRA") == 0) { snprintf (_colorFormat, sizeof(_colorFormat), "RGB32"); _outOffset = 1; _planes = 4; } if (g_strcmp0 (xFormat->name, "RGBA") == 0) { snprintf (_colorFormat, sizeof(_colorFormat), "BGR32"); _outOffset = 1; _planes = 4; } #else if (g_strcmp0 (xFormat->name, "ABGR") == 0) { snprintf (_colorFormat, sizeof(_colorFormat), "BGR32"); _outOffset = -1; _planes = 4; } if (g_strcmp0 (xFormat->name, "ARGB") == 0) { snprintf (_colorFormat, sizeof(_colorFormat), "RGB32"); _outOffset = -1; _planes = 4; } #endif PTRACE(4, "X11\tUsing color format: " << _colorFormat); PTRACE(4, "X11\tPlanes: " << _planes); PVideoFrameInfo srcFrameInfo, dstFrameInfo; srcFrameInfo.SetFrameSize(_imageWidth,_imageHeight); dstFrameInfo.SetFrameSize(_imageWidth,_imageHeight); dstFrameInfo.SetColourFormat(_colorFormat); _colorConverter = PColourConverter::Create(srcFrameInfo, dstFrameInfo); if (!_colorConverter) return 0; _frameBuffer = boost::shared_ptr<void> (malloc (_imageWidth * _imageHeight * _planes), free); // detect the window manager type _wmType = GetWMType (); CalculateSize (windowWidth, windowHeight, true); return 1; }
static DFBResult primaryInitScreen( CoreScreen *screen, CoreGraphicsDevice *device, void *driver_data, void *screen_data, DFBScreenDescription *description ) { DFBX11 *x11 = driver_data; DFBX11Shared *shared = x11->shared; void *old_error_handler = 0; D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ ); /* Set the screen capabilities. */ description->caps = DSCCAPS_OUTPUTS; description->outputs = 1; /* Set the screen name. */ snprintf( description->name, DFB_SCREEN_DESC_NAME_LENGTH, "X11/VDPAU Primary Screen" ); shared->depth = DefaultDepthOfScreen( x11->screenptr ); XSetWindowAttributes attr = { .background_pixmap = 0 }; attr.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | ExposureMask | StructureNotifyMask; XLockDisplay( x11->display ); old_error_handler = XSetErrorHandler( error_handler ); error_code = 0; shared->window = XCreateWindow( x11->display, RootWindowOfScreen(x11->screenptr), 0, 0, shared->screen_size.w, shared->screen_size.h, 0, shared->depth, InputOutput, DefaultVisualOfScreen(x11->screenptr), CWEventMask, &attr ); XSync( x11->display, False ); if (!shared->window || error_code) { D_ERROR( "DirectFB/X11/VDPAU: XCreateWindow() failed!\n" ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } XSelectInput( x11->display, shared->window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask ); XSizeHints Hints; /* * Here we inform the function of what we are going to change for the * window (there's also PPosition but it's obsolete) */ Hints.flags = PSize | PMinSize | PMaxSize; /* * Now we set the structure to the values we need for width & height. * For esthetic reasons we set Width=MinWidth=MaxWidth. * The same goes for Height. You can try whith differents values, or * let's use Hints.flags=Psize; and resize your window.. */ Hints.min_width = Hints.max_width = Hints.base_width = shared->screen_size.w; Hints.min_height = Hints.max_height = Hints.base_height = shared->screen_size.h; /* Now we can set the size hints for the specified window */ XSetWMNormalHints( x11->display, shared->window, &Hints ); /* We change the title of the window (default:Untitled) */ XStoreName( x11->display, shared->window, "DirectFB/VDPAU" ); /* maps the window and raises it to the top of the stack */ XMapRaised( x11->display, shared->window ); XSetErrorHandler( old_error_handler ); VdpStatus status; status = x11->vdp.PresentationQueueTargetCreateX11( x11->vdp.device, shared->window, &shared->vdp_target ); if (status) { D_ERROR( "DirectFB/X11/VDPAU: PresentationQueueTargetCreateX11() failed (status %d, '%s')!\n", status, x11->vdp.GetErrorString( status ) ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } status = x11->vdp.PresentationQueueCreate( x11->vdp.device, shared->vdp_target, &shared->vdp_queue ); if (status) { D_ERROR( "DirectFB/X11/VDPAU: PresentationQueueCreate() failed (status %d, '%s')!\n", status, x11->vdp.GetErrorString( status ) ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } status = x11->vdp.OutputSurfaceCreate( x11->vdp.device, VDP_RGBA_FORMAT_B8G8R8A8, shared->screen_size.w, shared->screen_size.h, &shared->vdp_surface ); if (status) { D_ERROR( "DirectFB/X11/VDPAU: OutputSurfaceCreate( RGBA %dx%d ) failed (status %d, '%s')!\n", shared->screen_size.w, shared->screen_size.h, status, x11->vdp.GetErrorString( status ) ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } DFBResult ret; CoreSurfaceConfig config; config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS | CSCONF_PREALLOCATED; config.size.w = shared->screen_size.w; config.size.h = shared->screen_size.h; config.format = DSPF_ARGB; config.caps = DSCAPS_VIDEOONLY; config.preallocated[0].addr = NULL; config.preallocated[0].handle = shared->vdp_surface; config.preallocated[0].pitch = shared->screen_size.w * 4; ret = dfb_surface_create( x11->core, &config, CSTF_EXTERNAL | CSTF_PREALLOCATED, shared->vdp_surface, NULL, &shared->vdp_core_surface ); if (ret) { D_DERROR( ret, "DirectFB/Xine/VDPAU: Could not create preallocated output surface!\n" ); XUnlockDisplay( x11->display ); return ret; } XUnlockDisplay( x11->display ); return DFB_OK; } static DFBResult primaryShutdownScreen( CoreScreen *screen, void *driver_data, void *screen_data ) { DFBX11 *x11 = driver_data; DFBX11Shared *shared = x11->shared; VdpStatus status; status = x11->vdp.PresentationQueueDestroy( shared->vdp_queue ); if (status) D_ERROR( "DirectFB/X11/VDPAU: PresentationQueueDestroy() failed (status %d, '%s')!\n", status, x11->vdp.GetErrorString( status ) ); status = x11->vdp.PresentationQueueTargetDestroy( shared->vdp_target ); if (status) D_ERROR( "DirectFB/X11/VDPAU: PresentationQueueTargetDestroy() failed (status %d, '%s')!\n", status, x11->vdp.GetErrorString( status ) ); XDestroyWindow( x11->display, shared->window ); return DFB_OK; }
static void XUNLOCKDISPLAY(Display *dpy) { if( useXLockDisplay ) { XUnlockDisplay(dpy); } }
DFBResult dfb_x11_image_init_handler( DFBX11 *x11, x11Image *image ) { Visual *visual; XImage *ximage; D_MAGIC_ASSERT( image, x11Image ); if (!x11->use_shm) return DFB_UNSUPPORTED; /* Lookup visual. */ visual = x11->visuals[DFB_PIXELFORMAT_INDEX(image->format)]; if (!visual) return DFB_UNSUPPORTED; image->visual = visual; XLockDisplay( x11->display ); ximage = XShmCreateImage( x11->display, image->visual, image->depth, ZPixmap, NULL, &image->seginfo, image->width, image->height ); if (!ximage) { D_ERROR( "X11/ShmImage: Error creating shared image (XShmCreateImage)!\n"); XUnlockDisplay( x11->display ); return DFB_FAILURE; } /* we firstly create our shared memory segment with the size we need, and correct permissions for the owner, the group and the world --> 0777 */ image->seginfo.shmid = shmget( IPC_PRIVATE, ximage->bytes_per_line * ximage->height, IPC_CREAT | 0777 ); if (image->seginfo.shmid < 0) goto error; /* Then, we have to attach the segment to our process, and we let the function search the correct memory place --> NULL. It's safest ! */ image->seginfo.shmaddr = shmat( image->seginfo.shmid, NULL, 0 ); if (!image->seginfo.shmaddr) goto error_shmat; ximage->data = image->seginfo.shmaddr; /* We set the buffer in Read and Write mode */ image->seginfo.readOnly = False; if (!XShmAttach( x11->display, &image->seginfo )) goto error_xshmattach; image->ximage = ximage; image->pitch = ximage->bytes_per_line; image->pixmap = XShmCreatePixmap( x11->display, DefaultRootWindow(x11->display), ximage->data, &image->seginfo, image->width, image->height, image->depth ); image->gc = XCreateGC( x11->display, image->pixmap, 0, NULL ); XUnlockDisplay( x11->display ); return DFB_OK; error_xshmattach: shmdt( image->seginfo.shmaddr ); error_shmat: shmctl( image->seginfo.shmid, IPC_RMID, NULL ); error: XDestroyImage( ximage ); XUnlockDisplay( x11->display ); return DFB_FAILURE; }
/* create the X11 window for DAZZLER display */ static void open_display(void) { Window rootwindow; XSizeHints *size_hints = XAllocSizeHints(); Atom wm_delete_window; display = XOpenDisplay(NULL); XLockDisplay(display); screen = DefaultScreen(display); rootwindow = RootWindow(display, screen); XGetWindowAttributes(display, rootwindow, &wa); window = XCreateSimpleWindow(display, rootwindow, 0, 0, size, size, 1, 0, 0); XStoreName(display, window, "Cromemco DAzzLER"); size_hints->flags = PSize | PMinSize | PMaxSize; size_hints->min_width = size; size_hints->min_height = size; size_hints->base_width = size; size_hints->base_height = size; size_hints->max_width = size; size_hints->max_height = size; XSetWMNormalHints(display, window, size_hints); XFree(size_hints); wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); XSetWMProtocols(display, window, &wm_delete_window, 1); colormap = DefaultColormap(display, 0); gc = XCreateGC(display, window, 0, NULL); XSetFillStyle(display, gc, FillSolid); pixmap = XCreatePixmap(display, rootwindow, size, size, wa.depth); XParseColor(display, colormap, color0, &colors[0]); XAllocColor(display, colormap, &colors[0]); XParseColor(display, colormap, color1, &colors[1]); XAllocColor(display, colormap, &colors[1]); XParseColor(display, colormap, color2, &colors[2]); XAllocColor(display, colormap, &colors[2]); XParseColor(display, colormap, color3, &colors[3]); XAllocColor(display, colormap, &colors[3]); XParseColor(display, colormap, color4, &colors[4]); XAllocColor(display, colormap, &colors[4]); XParseColor(display, colormap, color5, &colors[5]); XAllocColor(display, colormap, &colors[5]); XParseColor(display, colormap, color6, &colors[6]); XAllocColor(display, colormap, &colors[6]); XParseColor(display, colormap, color7, &colors[7]); XAllocColor(display, colormap, &colors[7]); XParseColor(display, colormap, color8, &colors[8]); XAllocColor(display, colormap, &colors[8]); XParseColor(display, colormap, color9, &colors[9]); XAllocColor(display, colormap, &colors[9]); XParseColor(display, colormap, color10, &colors[10]); XAllocColor(display, colormap, &colors[10]); XParseColor(display, colormap, color11, &colors[11]); XAllocColor(display, colormap, &colors[11]); XParseColor(display, colormap, color12, &colors[12]); XAllocColor(display, colormap, &colors[12]); XParseColor(display, colormap, color13, &colors[13]); XAllocColor(display, colormap, &colors[13]); XParseColor(display, colormap, color14, &colors[14]); XAllocColor(display, colormap, &colors[14]); XParseColor(display, colormap, color15, &colors[15]); XAllocColor(display, colormap, &colors[15]); XParseColor(display, colormap, gray0, &grays[0]); XAllocColor(display, colormap, &grays[0]); XParseColor(display, colormap, gray1, &grays[1]); XAllocColor(display, colormap, &grays[1]); XParseColor(display, colormap, gray2, &grays[2]); XAllocColor(display, colormap, &grays[2]); XParseColor(display, colormap, gray3, &grays[3]); XAllocColor(display, colormap, &grays[3]); XParseColor(display, colormap, gray4, &grays[4]); XAllocColor(display, colormap, &grays[4]); XParseColor(display, colormap, gray5, &grays[5]); XAllocColor(display, colormap, &grays[5]); XParseColor(display, colormap, gray6, &grays[6]); XAllocColor(display, colormap, &grays[6]); XParseColor(display, colormap, gray7, &grays[7]); XAllocColor(display, colormap, &grays[7]); XParseColor(display, colormap, gray8, &grays[8]); XAllocColor(display, colormap, &grays[8]); XParseColor(display, colormap, gray9, &grays[9]); XAllocColor(display, colormap, &grays[9]); XParseColor(display, colormap, gray10, &grays[10]); XAllocColor(display, colormap, &grays[10]); XParseColor(display, colormap, gray11, &grays[11]); XAllocColor(display, colormap, &grays[11]); XParseColor(display, colormap, gray12, &grays[12]); XAllocColor(display, colormap, &grays[12]); XParseColor(display, colormap, gray13, &grays[13]); XAllocColor(display, colormap, &grays[13]); XParseColor(display, colormap, gray14, &grays[14]); XAllocColor(display, colormap, &grays[14]); XParseColor(display, colormap, gray15, &grays[15]); XAllocColor(display, colormap, &grays[15]); XMapWindow(display, window); XUnlockDisplay(display); }
static DFBResult x11Read( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceAllocation *allocation, void *alloc_data, void *destination, int pitch, const DFBRectangle *rect ) { XImage *image; XImage *sub; x11PoolLocalData *local = pool_local; x11AllocationData *alloc = alloc_data; DFBX11 *x11 = local->x11; D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation ); D_DEBUG_AT( X11_Surfaces, " -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_ASSERT( destination != NULL ); D_ASSERT( pitch >= 0 ); DFB_RECTANGLE_ASSERT( rect ); D_DEBUG_AT( X11_Surfaces, " => %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) ); XLockDisplay( x11->display ); #if 1 image = XCreateImage( x11->display, alloc->visual, alloc->depth, ZPixmap, 0, destination, rect->w, rect->h, 32, pitch ); if (!image) { D_ERROR( "X11/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } sub = XGetSubImage( x11->display, alloc->xid, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap, image, 0, 0 ); #else image = XGetImage( x11->display, alloc->window ? alloc->window : alloc->xid, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap ); #endif if (image) { // dfb_surface_buffer_dump_type_locked2( allocation->buffer, ".", "x11Read", false, image->data, image->bytes_per_line ); /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */ image->data = NULL; XDestroyImage( image ); } XUnlockDisplay( x11->display ); #if 1 if (!sub) { D_ERROR( "X11/Surfaces: XGetSubImage( %d,%d-%dx%d ) failed!\n", DFB_RECTANGLE_VALS(rect) ); return DFB_FAILURE; } #endif return DFB_OK; }
static DFBResult x11DeallocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { DFBResult ret = DFB_OK; x11AllocationData *alloc = alloc_data; x11PoolLocalData *local = pool_local; DFBX11 *x11 = local->x11; D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); CORE_SURFACE_ALLOCATION_ASSERT( allocation ); XLockDisplay( x11->display ); if (alloc->gc) XFreeGC( x11->display, alloc->gc ); switch (alloc->type) { case X11_ALLOC_WINDOW: D_ASSUME( x11->showing != alloc->window ); if (x11->showing == alloc->window) { D_LOG( X11_Surfaces, VERBOSE, " -> Hiding window 0x%08lx that is to be destroyed!!!\n", x11->showing ); XUnmapWindow( x11->display, x11->showing ); x11->showing = 0; } case X11_ALLOC_PIXMAP: if (allocation->type & CSTF_PREALLOCATED) { // don't delete } else if (alloc->created) { if (alloc->xid != alloc->window) { D_INFO( "X11/Windows: Free Pixmap 0x%08lx\n", alloc->xid ); XFreePixmap( x11->display, alloc->xid ); } if (alloc->window) { D_INFO( "X11/Windows: Destroy Window 0x%08lx\n", alloc->window ); XDestroyWindow( x11->display, alloc->window ); } } break; default: D_BUG( "unexpected allocation type %d\n", alloc->type ); ret = DFB_BUG; } XUnlockDisplay( x11->display ); return ret; }
ScopedXLock::~ScopedXLock() { XUnlockDisplay (display); }
char *Sys_GetClipboardData( clipboard_t clip ) { #ifdef BUILD_CLIENT // derived from SDL clipboard code (http://hg.assembla.com/SDL_Clipboard) Window owner; Atom selection; Atom converted; Atom selectionType; int selectionFormat; unsigned long nbytes; unsigned long overflow; char *src; if ( x11.display == NULL ) { SDL_SysWMinfo info; SDL_VERSION( &info.version ); if ( SDL_GetWindowWMInfo( (SDL_Window*) IN_GetWindow(), &info ) != 1 || info.subsystem != SDL_SYSWM_X11 ) { Com_Printf("Not on X11? (%d)\n",info.subsystem); return NULL; } x11.display = info.info.x11.display; x11.window = info.info.x11.window; x11.utf8 = XInternAtom( x11.display, "UTF8_STRING", False ); SDL_EventState( SDL_SYSWMEVENT, SDL_ENABLE ); //SDL_SetEventFilter( Sys_ClipboardFilter ); } XLockDisplay( x11.display ); switch ( clip ) { // preference order; we use fall-through default: // SELECTION_CLIPBOARD selection = XInternAtom( x11.display, "CLIPBOARD", False ); owner = XGetSelectionOwner( x11.display, selection ); if ( owner != None && owner != x11.window ) { break; } case SELECTION_PRIMARY: selection = XA_PRIMARY; owner = XGetSelectionOwner( x11.display, selection ); if ( owner != None && owner != x11.window ) { break; } case SELECTION_SECONDARY: selection = XA_SECONDARY; owner = XGetSelectionOwner( x11.display, selection ); } converted = XInternAtom( x11.display, "UNVANQUISHED_SELECTION", False ); XUnlockDisplay( x11.display ); if ( owner == None || owner == x11.window ) { selection = XA_CUT_BUFFER0; owner = RootWindow( x11.display, DefaultScreen( x11.display ) ); } else { SDL_Event event; XLockDisplay( x11.display ); owner = x11.window; //FIXME: when we can respond to clipboard requests, don't alter selection XConvertSelection( x11.display, selection, x11.utf8, converted, owner, CurrentTime ); XUnlockDisplay( x11.display ); for (;;) { SDL_WaitEvent( &event ); if ( event.type == SDL_SYSWMEVENT ) { #if SDL_VERSION_ATLEAST( 2, 0, 0 ) XEvent xevent = event.syswm.msg->msg.x11.event; #else XEvent xevent = event.syswm.msg->event.xevent; #endif if ( xevent.type == SelectionNotify && xevent.xselection.requestor == owner ) { break; } } } } XLockDisplay( x11.display ); if ( XGetWindowProperty( x11.display, owner, converted, 0, INT_MAX / 4, False, x11.utf8, &selectionType, &selectionFormat, &nbytes, &overflow, (unsigned char **) &src ) == Success ) { char *dest = NULL; if ( selectionType == x11.utf8 ) { dest = (char*) Z_Malloc( nbytes + 1 ); memcpy( dest, src, nbytes ); dest[ nbytes ] = 0; } XFree( src ); XUnlockDisplay( x11.display ); return dest; } XUnlockDisplay( x11.display ); #endif // !BUILD_SERVER return NULL; }
PyObject * X11Display_PyObject__handle_events(X11Display_PyObject * self, PyObject * args) { PyObject *events = PyList_New(0), *o; XEvent ev; XLockDisplay(self->display); XSync(self->display, False); while (XPending(self->display)) { XNextEvent(self->display, &ev); //printf("EVENT: %d\n", ev.type); if (ev.type == Expose) { o = Py_BuildValue("(i{s:i,s:(ii),s:(ii)})", Expose, "window", ev.xexpose.window, "pos", ev.xexpose.x, ev.xexpose.y, "size", ev.xexpose.width, ev.xexpose.height); PyList_Append(events, o); Py_DECREF(o); } else if (ev.type == KeyPress || ev.type == KeyRelease) { char buf[100]; KeySym keysym; static XComposeStatus stat; int key; // Peeled shamelessly from MPlayer. XLookupString(&ev.xkey, buf, sizeof(buf), &keysym, &stat); key = ((keysym & 0xff00) != 0 ? ((keysym & 0x00ff) + 256) : (keysym)); o = Py_BuildValue("(i{s:i,s:i,s:s#})", ev.type, "window", ev.xkey.window, "key", key, "raw", &ev, sizeof(ev)); PyList_Append(events, o); Py_DECREF(o); } else if (ev.type == ButtonPress || ev.type == ButtonRelease) { o = Py_BuildValue("(i{s:i,s:(ii),s:(ii),s:i,s:i,s:s#})", ev.type, "window", ev.xbutton.window, "pos", ev.xbutton.x, ev.xbutton.y, "root_pos", ev.xbutton.x_root, ev.xbutton.y_root, "state", ev.xbutton.state, "button", ev.xbutton.button, "raw", &ev, sizeof(ev)); PyList_Append(events, o); Py_DECREF(o); } else if (ev.type == MotionNotify) { o = Py_BuildValue("(i{s:i,s:(ii),s:(ii),s:s#})", MotionNotify, "window", ev.xmotion.window, "pos", ev.xmotion.x, ev.xmotion.y, "root_pos", ev.xmotion.x_root, ev.xmotion.y_root, "raw", &ev, sizeof(ev)); PyList_Append(events, o); Py_DECREF(o); } else if (ev.type == ConfigureNotify) { o = Py_BuildValue("(i{s:i,s:(ii),s:(ii)})", ConfigureNotify, "window", ev.xconfigure.window, "pos", ev.xconfigure.x, ev.xconfigure.y, "size", ev.xconfigure.width, ev.xconfigure.height); PyList_Append(events, o); Py_DECREF(o); } else if (ev.type == ClientMessage) { char *msgtype = "unknown"; if (ev.xclient.data.l[0] == self->wmDeleteMessage) msgtype = "delete"; o = Py_BuildValue("(i{s:i,s:s,s:s#})", ClientMessage, "window", ev.xclient.window, "type", msgtype, "raw", &ev, sizeof(ev)); PyList_Append(events, o); Py_DECREF(o); } else if (ev.type == MapNotify || ev.type == UnmapNotify) { o = Py_BuildValue("(i{s:i})", ev.type, "window", ev.xmap.window); PyList_Append(events, o); Py_DECREF(o); } else if (ev.type == FocusIn || ev.type == FocusOut) { o = Py_BuildValue("(i{s:i})", ev.xfocus.type, "window", ev.xfocus.window); PyList_Append(events, o); Py_DECREF(o); } } XUnlockDisplay(self->display); // printf("END HANDL EVENTS\n"); return events; }
void GlContext::create(uint32_t _width, uint32_t _height) { BX_UNUSED(_width, _height); XLockDisplay(s_display); int major, minor; bool version = glXQueryVersion(s_display, &major, &minor); BGFX_FATAL(version, Fatal::UnableToInitialize, "Failed to query GLX version"); BGFX_FATAL( (major == 1 && minor >= 2) || major > 1 , Fatal::UnableToInitialize , "GLX version is not >=1.2 (%d.%d)." , major , minor ); int32_t screen = DefaultScreen(s_display); const char* extensions = glXQueryExtensionsString(s_display, screen); BX_TRACE("GLX extensions:"); dumpExtensions(extensions); const int attrsGlx[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DOUBLEBUFFER, true, GLX_RED_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_GREEN_SIZE, 8, // GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, 0, }; // Find suitable config GLXFBConfig bestConfig = NULL; int numConfigs; GLXFBConfig* configs = glXChooseFBConfig(s_display, screen, attrsGlx, &numConfigs); BX_TRACE("glX num configs %d", numConfigs); XVisualInfo* visualInfo = NULL; for (int ii = 0; ii < numConfigs; ++ii) { visualInfo = glXGetVisualFromFBConfig(s_display, configs[ii]); if (NULL != visualInfo) { BX_TRACE("---"); bool valid = true; for (uint32_t attr = 6; attr < BX_COUNTOF(attrsGlx)-1 && attrsGlx[attr] != None; attr += 2) { int value; glXGetFBConfigAttrib(s_display, configs[ii], attrsGlx[attr], &value); BX_TRACE("glX %d/%d %2d: %4x, %8x (%8x%s)" , ii , numConfigs , attr/2 , attrsGlx[attr] , value , attrsGlx[attr + 1] , value < attrsGlx[attr + 1] ? " *" : "" ); if (value < attrsGlx[attr + 1]) { valid = false; #if !BGFX_CONFIG_DEBUG break; #endif // BGFX_CONFIG_DEBUG } } if (valid) { bestConfig = configs[ii]; BX_TRACE("Best config %d.", ii); break; } } XFree(visualInfo); visualInfo = NULL; } XFree(configs); BGFX_FATAL(visualInfo, Fatal::UnableToInitialize, "Failed to find a suitable X11 display configuration."); BX_TRACE("Create GL 2.1 context."); m_context = glXCreateContext(s_display, visualInfo, 0, GL_TRUE); BGFX_FATAL(NULL != m_context, Fatal::UnableToInitialize, "Failed to create GL 2.1 context."); XFree(visualInfo); #if BGFX_CONFIG_RENDERER_OPENGL >= 31 glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress( (const GLubyte*)"glXCreateContextAttribsARB"); if (NULL != glXCreateContextAttribsARB) { BX_TRACE("Create GL 3.1 context."); const int contextAttrs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, 0, }; GLXContext context = glXCreateContextAttribsARB(s_display, bestConfig, 0, true, contextAttrs); if (NULL != context) { glXDestroyContext(s_display, m_context); m_context = context; } } #else BX_UNUSED(bestConfig); #endif // BGFX_CONFIG_RENDERER_OPENGL >= 31 XUnlockDisplay(s_display); import(); glXMakeCurrent(s_display, s_window, m_context); glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalEXT"); if (NULL != glXSwapIntervalEXT) { BX_TRACE("Using glXSwapIntervalEXT."); glXSwapIntervalEXT(s_display, s_window, 0); } else { glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalMESA"); if (NULL != glXSwapIntervalMESA) { BX_TRACE("Using glXSwapIntervalMESA."); glXSwapIntervalMESA(0); } else { glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalSGI"); if (NULL != glXSwapIntervalSGI) { BX_TRACE("Using glXSwapIntervalSGI."); glXSwapIntervalSGI(0); } } } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glXSwapBuffers(s_display, s_window); }
Bool dfb_x11_open_window( DFBX11 *x11, XWindow** ppXW, int iXPos, int iYPos, int iWidth, int iHeight, DFBSurfacePixelFormat format ) { XWindow *xw; XSetWindowAttributes attr = { .background_pixmap = 0 }; void *old_error_handler = 0; unsigned int cw_mask = CWEventMask; D_DEBUG_AT( X11_Window, "Creating %4dx%4d %s window...\n", iWidth, iHeight, dfb_pixelformat_name(format) ); xw = D_CALLOC( 1, sizeof(XWindow) ); if (!xw) return D_OOM(); /* We set the structure as needed for our window */ xw->width = iWidth; xw->height = iHeight; xw->display = x11->display; xw->screenptr = DefaultScreenOfDisplay(xw->display); xw->screennum = DefaultScreen(xw->display); xw->depth = DefaultDepthOfScreen(xw->screenptr); xw->visual = DefaultVisualOfScreen(xw->screenptr); attr.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | ExposureMask | StructureNotifyMask; if (dfb_config->x11_borderless) { attr.override_redirect = True; cw_mask |= CWOverrideRedirect; } XLockDisplay( x11->display ); old_error_handler = XSetErrorHandler( error_handler ); error_code = 0; xw->window = XCreateWindow( xw->display, RootWindowOfScreen(xw->screenptr), iXPos, iYPos, iWidth, iHeight, 0, xw->depth, InputOutput, xw->visual, cw_mask, &attr ); XSync( xw->display, False ); if (!xw->window || error_code) { D_FREE( xw ); XUnlockDisplay( x11->display ); return False; } XSizeHints Hints; /* * Here we inform the function of what we are going to change for the * window (there's also PPosition but it's obsolete) */ Hints.flags = PSize | PMinSize | PMaxSize; /* * Now we set the structure to the values we need for width & height. * For esthetic reasons we set Width=MinWidth=MaxWidth. * The same goes for Height. You can try whith differents values, or * let's use Hints.flags=Psize; and resize your window.. */ Hints.min_width = Hints.max_width = Hints.base_width = xw->width; Hints.min_height = Hints.max_height = Hints.base_height = xw->height; /* Now we can set the size hints for the specified window */ XSetWMNormalHints(xw->display,xw->window,&Hints); /* We change the title of the window (default:Untitled) */ XStoreName(xw->display,xw->window,"DFB X11 system window"); xw->gc = XCreateGC(xw->display, xw->window, 0, NULL); #if 0 // Create a null cursor Pixmap pixmp1; Pixmap pixmp2; XColor fore; XColor back; char zero = 0; pixmp1 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 ); pixmp2 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 ); xw->NullCursor = XCreatePixmapCursor( xw->display, pixmp1, pixmp2, &fore, &back, 0, 0 ); XFreePixmap ( xw->display, pixmp1 ); XFreePixmap ( xw->display, pixmp2 ); XDefineCursor( xw->display, xw->window, xw->NullCursor ); #endif /* maps the window and raises it to the top of the stack */ XMapRaised( xw->display, xw->window ); if (x11->use_shm) { // Shared memory xw->shmseginfo=(XShmSegmentInfo *)D_CALLOC(1, sizeof(XShmSegmentInfo)); if (!xw->shmseginfo) { x11->use_shm = false; goto no_shm; } xw->ximage=XShmCreateImage(xw->display, xw->visual, xw->depth, ZPixmap, NULL,xw->shmseginfo, xw->width, xw->height * 2); XSync( xw->display, False ); if (!xw->ximage || error_code) { D_ERROR("X11: Error creating shared image (XShmCreateImage) \n"); x11->use_shm = false; D_FREE(xw->shmseginfo); error_code = 0; goto no_shm; } xw->bpp = (xw->ximage->bits_per_pixel + 7) / 8; /* we firstly create our shared memory segment with the size we need, and correct permissions for the owner, the group and the world --> 0777 */ xw->shmseginfo->shmid=shmget(IPC_PRIVATE, xw->ximage->bytes_per_line * xw->ximage->height * 2, IPC_CREAT|0777); if (xw->shmseginfo->shmid<0) { x11->use_shm = false; XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); goto no_shm; } /* Then, we have to attach the segment to our process, and we let the function search the correct memory place --> NULL. It's safest ! */ xw->shmseginfo->shmaddr = shmat( xw->shmseginfo->shmid, NULL, 0 ); if (!xw->shmseginfo->shmaddr) { x11->use_shm = false; shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL); XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); goto no_shm; } /* We set the buffer in Read and Write mode */ xw->shmseginfo->readOnly=False; xw->virtualscreen= xw->ximage->data = xw->shmseginfo->shmaddr; XSetErrorHandler( error_handler_shm ); XShmAttach(x11->display,xw->shmseginfo); XShmPutImage(x11->display, xw->window, xw->gc, xw->ximage, 0, 0, 0, 0, 1, 1, False); XSync(x11->display, False); XSetErrorHandler( error_handler ); if (!x11->use_shm) { shmdt(xw->shmseginfo->shmaddr); shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL); XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); } } no_shm: if (!x11->use_shm) { int pitch; xw->bpp = (xw->depth > 16) ? 4 : (xw->depth > 8) ? 2 : 1; pitch = (xw->bpp * xw->width + 3) & ~3; /* Use malloc(), not D_MALLOC() here, because XCreateImage() * will call free() on this data. */ xw->virtualscreen = malloc ( 2 * xw->height * pitch ); xw->ximage = XCreateImage( xw->display, xw->visual, xw->depth, ZPixmap, 0, xw->virtualscreen, xw->width, xw->height * 2, 32, pitch ); XSync( xw->display, False ); if (!xw->ximage || error_code) { D_ERROR( "X11/Window: XCreateImage( Visual %02lu, depth %d, size %dx%d, buffer %p [%d] ) failed!\n", xw->visual->visualid, xw->depth, xw->width, xw->height * 2, xw->virtualscreen, pitch ); XFreeGC(xw->display,xw->gc); XDestroyWindow(xw->display,xw->window); XSetErrorHandler( old_error_handler ); XUnlockDisplay( x11->display ); D_FREE( xw ); return False; } } XSetErrorHandler( old_error_handler ); XUnlockDisplay( x11->display ); D_INFO( "X11/Display: %ssing XShm.\n", x11->use_shm ? "U" : "Not u" ); (*ppXW) = xw; return True; } void dfb_x11_close_window( DFBX11 *x11, XWindow* xw ) { if (x11->use_shm) { XShmDetach( xw->display, xw->shmseginfo ); shmdt( xw->shmseginfo->shmaddr ); shmctl( xw->shmseginfo->shmid, IPC_RMID, NULL ); D_FREE( xw->shmseginfo ); } XDestroyImage( xw->ximage ); XFreeGC( xw->display, xw->gc ); XDestroyWindow( xw->display, xw->window ); #if 0 XFreeCursor( xw->display, xw->NullCursor ); #endif D_FREE( xw ); }
bool XWindow::ProcessEvents() { XEvent event; bool ret = false; XLockDisplay (_display); while (XCheckWindowEvent (_display, _XWindow, StructureNotifyMask | SubstructureRedirectMask | ExposureMask | KeyPressMask | ButtonPressMask, &event) == True) { switch (event.type) { case ClientMessage: // If "closeWindow" is clicked do nothing right now // (window is closed from the GUI) break; case ConfigureNotify: { // the window size has changed XConfigureEvent *xce = &(event.xconfigure); // if a slave window exists it has to be resized as well if (_slave) _slave->SetWindow (xce->width - (int) (xce->width / ( _state.fullscreen ? PIP_RATIO_FS : PIP_RATIO_WIN)), xce->height - (int) (_slave->GetYUVHeight () * xce->width / ( _state.fullscreen ? PIP_RATIO_FS : PIP_RATIO_WIN) / _slave->GetYUVWidth ()), (int) (xce->width / ( _state.fullscreen ? PIP_RATIO_FS : PIP_RATIO_WIN)), (int) (_slave->GetYUVHeight () * xce->width / ( _state.fullscreen ? PIP_RATIO_FS : PIP_RATIO_WIN) / _slave->GetYUVWidth ())); CalculateSize (xce->width, xce->height, true); if( _paintColorKey ) { XSetForeground( _display, _gc, _colorKey ); XFillRectangle( _display, _XWindow, _gc, _state.curX, _state.curY, _state.curWidth, _state.curHeight); } } break; case Expose: if (_paintColorKey) { XSetForeground( _display, _gc, _colorKey ); XFillRectangle( _display, _XWindow, _gc, _state.curX, _state.curY, _state.curWidth, _state.curHeight); } ret = true; break; case KeyPress: // a key is pressed { XKeyEvent *xke = &(event.xkey); switch (xke->keycode) { case 41: if (_master) _master->ToggleFullscreen (); else ToggleFullscreen (); // "f" break; case 40: if (_master) _master->ToggleDecoration (); else ToggleDecoration (); // "d" break; case 32: if (_master) _master->ToggleOntop (); else ToggleOntop (); // "o" break; case 9: if (_master) { if (_master->IsFullScreen ()) _master->ToggleFullscreen(); } // esc else { if (IsFullScreen ()) ToggleFullscreen(); } break; default: break; } } break; case ButtonPress: // a mouse button is clicked if (_master) if (!_master->HasDecoration()) _master->ToggleDecoration(); else _master->ToggleFullscreen(); else if (!_state.decoration) ToggleDecoration(); else ToggleFullscreen(); break; case DestroyNotify: PTRACE(4, "X11\tWindow is being destroyed"); break; default: PTRACE(1, "X11\tUnknown X Event " << event.type << " received"); } } XUnlockDisplay (_display); return ret; }
// // I_GetClipboardText // // by Denis Lukianov - 20 Mar 2006 // Cross-platform clipboard functionality // std::string I_GetClipboardText (void) { #ifdef X11 std::string ret; Display *dis = XOpenDisplay(NULL); int screen = DefaultScreen(dis); if(!dis) { Printf(PRINT_HIGH, "I_GetClipboardText: XOpenDisplay failed"); return ""; } XLockDisplay(dis); Window WindowEvents = XCreateSimpleWindow(dis, RootWindow(dis, screen), 0, 0, 1, 1, 0, BlackPixel(dis, screen), BlackPixel(dis, screen)); if(XGetSelectionOwner(dis, XA_PRIMARY) != None) { if(!XConvertSelection(dis, XA_PRIMARY, XA_STRING, XA_PRIMARY, WindowEvents, CurrentTime)) { XDestroyWindow(dis, WindowEvents); XUnlockDisplay(dis); XCloseDisplay(dis); Printf(PRINT_HIGH, "I_GetClipboardText: XConvertSelection failed"); return ""; } XFlush (dis); // Wait for the reply for(;;) { XEvent e; XNextEvent(dis, &e); if(e.type == SelectionNotify) break; } Atom type; int format, result; u_long len, bytes_left, temp; u_char *data; result = XGetWindowProperty(dis, WindowEvents, XA_PRIMARY, 0, 0, False, AnyPropertyType, &type, &format, &len, &bytes_left, &data); if(result != Success) { XDestroyWindow(dis, WindowEvents); XUnlockDisplay(dis); XCloseDisplay(dis); Printf(PRINT_HIGH, "I_GetClipboardText: XGetWindowProperty failed(1)"); return ""; } if(!bytes_left) { XDestroyWindow(dis, WindowEvents); DPrintf("I_GetClipboardText: Len was: %d", len); XUnlockDisplay(dis); XCloseDisplay(dis); return ""; } result = XGetWindowProperty(dis, WindowEvents, XA_PRIMARY, 0, bytes_left, False, AnyPropertyType, &type, &format, &len, &temp, &data); if(result != Success) { XDestroyWindow(dis, WindowEvents); XUnlockDisplay(dis); XCloseDisplay(dis); Printf(PRINT_HIGH, "I_GetClipboardText: XGetWindowProperty failed(2)"); return ""; } ret = std::string((const char *)data, len); XFree(data); } XDestroyWindow(dis, WindowEvents); XUnlockDisplay(dis); XCloseDisplay(dis); return ret; #endif #if defined _WIN32 && !defined _XBOX std::string ret; if(!IsClipboardFormatAvailable(CF_TEXT)) return ""; if(!OpenClipboard(NULL)) return ""; HANDLE hClipboardData = GetClipboardData(CF_TEXT); if(!hClipboardData) { CloseClipboard(); return ""; } const char *cData = reinterpret_cast<const char *>(GlobalLock(hClipboardData)); SIZE_T uiSize = static_cast<SIZE_T>(GlobalSize(hClipboardData)); if(cData && uiSize) { for(size_t i = 0; i < uiSize; i++) { if(!cData[i]) { uiSize = i; break; } } ret = std::string(cData, uiSize); } GlobalUnlock(hClipboardData); CloseClipboard(); return ret; #endif #ifdef OSX ScrapRef scrap; Size size; int err = GetCurrentScrap(&scrap); if(err) { Printf(PRINT_HIGH, "GetCurrentScrap error: %d", err); return ""; } err = GetScrapFlavorSize(scrap, FOUR_CHAR_CODE('TEXT'), &size); if(err) { Printf(PRINT_HIGH, "GetScrapFlavorSize error: %d", err); return ""; } char *data = new char[size+1]; err = GetScrapFlavorData(scrap, FOUR_CHAR_CODE('TEXT'), &size, data); data[size] = 0; if(err) { Printf(PRINT_HIGH, "GetScrapFlavorData error: %d", err); delete[] data; return ""; } std::string ret(data); delete[] data; return ret; #endif return ""; }
int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage) { int x, y, n, k; rdpShadowServer* server; rdpShadowSurface* surface; server = subsystem->server; surface = server->surface; if (getImage) { #ifdef WITH_XFIXES UINT32* pDstPixel; XFixesCursorImage* ci; XLockDisplay(subsystem->display); ci = XFixesGetCursorImage(subsystem->display); XUnlockDisplay(subsystem->display); if (!ci) return -1; x = ci->x; y = ci->y; if (ci->width > subsystem->cursorMaxWidth) return -1; if (ci->height > subsystem->cursorMaxHeight) return -1; subsystem->cursorHotX = ci->xhot; subsystem->cursorHotY = ci->yhot; subsystem->cursorWidth = ci->width; subsystem->cursorHeight = ci->height; subsystem->cursorId = ci->cursor_serial; n = ci->width * ci->height; pDstPixel = (UINT32*) subsystem->cursorPixels; for (k = 0; k < n; k++) { /* XFixesCursorImage.pixels is in *unsigned long*, which may be 8 bytes */ *pDstPixel++ = (UINT32) ci->pixels[k]; } XFree(ci); x11_shadow_pointer_alpha_update(subsystem); #endif } else { UINT32 mask; int win_x, win_y; int root_x, root_y; Window root, child; XLockDisplay(subsystem->display); if (!XQueryPointer(subsystem->display, subsystem->root_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) { XUnlockDisplay(subsystem->display); return -1; } XUnlockDisplay(subsystem->display); x = root_x; y = root_y; } /* Convert to offset based on current surface */ if (surface) { x -= surface->x; y -= surface->y; } if ((x != subsystem->pointerX) || (y != subsystem->pointerY)) { subsystem->pointerX = x; subsystem->pointerY = y; x11_shadow_pointer_position_update(subsystem); } return 1; }
void WebBrowserObject::BrowserEvent(const char *etype, const char *data) { if (!strcmp(etype, "key")) { int key = NoSymbol, state = 0; // Check for modifiers if (!strncmp(data, "ctrl:", 5)) { state = ControlMask; data += 5; } else if (!strncmp(data, "shift:", 6)) { state = ShiftMask; data += 6; } else if (!strncmp(data, "mod1:", 5)) { state = Mod1Mask; data += 5; } // Predefined key codes if (!strcmp(data, "home")) { key = XK_Home; } else if (!strcmp(data, "end")) { key = XK_End; } else if (!strcmp(data, "prevpage")) { key = XK_Page_Up; } else if (!strcmp(data, "nextpage")) { key = XK_Page_Down; } else if (!strcmp(data, "up")) { key = XK_Up; } else if (!strcmp(data, "down")) { key = XK_Down; } else if (!strcmp(data, "prev")) { key = XK_Left; } else if (!strcmp(data, "next")) { key = XK_Right; } else if (!strcmp(data, "accept")) { key = XK_Return; } else if (!strcmp(data, "nexttrack")) { key = XK_Tab; } else if (!strcmp(data, "prevtrack")) { key = XK_Tab; state = ShiftMask; } else { key = XStringToKeysym(data); } if (key && toplevel) { XKeyEvent event; event.display = GDK_WINDOW_XDISPLAY(toplevel->window); event.window = GDK_WINDOW_XID(toplevel->window); event.root = DefaultRootWindow(event.display); event.subwindow = None; event.time = CurrentTime; event.x = 1; event.y = 1; event.x_root = 1; event.y_root = 1; event.same_screen = TRUE; event.type = KeyPress; event.state = state; XLockDisplay(event.display); event.keycode = XKeysymToKeycode(event.display,key); XSendEvent(event.display, event.window, TRUE, KeyPressMask, (XEvent *)&event); XUnlockDisplay(event.display); } } else if (!strcmp(etype, "focus")) { if (!strcmp(data, "mozilla") && toplevel) { XLockDisplay(GDK_WINDOW_XDISPLAY(toplevel->window)); XRaiseWindow(GDK_WINDOW_XDISPLAY(toplevel->window), GDK_WINDOW_XID(toplevel->window)); XSync(GDK_WINDOW_XDISPLAY(toplevel->window), False); XUnlockDisplay(GDK_WINDOW_XDISPLAY(toplevel->window)); gtk_widget_grab_focus(toplevel); } else if (!strcmp(data, "url") && toplevel) { gtk_widget_grab_focus(urlEntry); } } else if (!strcmp(etype, "toolbar")) { if (!strToBool(data)) { if (toolbar_flag && toplevel) { gtk_container_remove(GTK_CONTAINER(toolbarHBox), toolbar); gtk_container_remove(GTK_CONTAINER(toolbarHBox), urlEntry); } toolbar_flag = 0; } else { if (!toolbar_flag && toplevel) { gtk_box_pack_start(GTK_BOX(toolbarHBox), toolbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(toolbarHBox), urlEntry, TRUE, TRUE, 0); } toolbar_flag = 1; } } }
void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem) { XEvent xevent; DWORD status; DWORD nCount; UINT64 cTime; DWORD dwTimeout; DWORD dwInterval; UINT64 frameTime; HANDLE events[32]; wMessage message; wMessagePipe* MsgPipe; MsgPipe = subsystem->MsgPipe; nCount = 0; events[nCount++] = subsystem->event; events[nCount++] = MessageQueue_Event(MsgPipe->In); subsystem->captureFrameRate = 16; dwInterval = 1000 / subsystem->captureFrameRate; frameTime = GetTickCount64() + dwInterval; while (1) { cTime = GetTickCount64(); dwTimeout = (cTime > frameTime) ? 0 : frameTime - cTime; status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout); if (WaitForSingleObject(MessageQueue_Event(MsgPipe->In), 0) == WAIT_OBJECT_0) { if (MessageQueue_Peek(MsgPipe->In, &message, TRUE)) { if (message.id == WMQ_QUIT) break; x11_shadow_subsystem_process_message(subsystem, &message); } } if (WaitForSingleObject(subsystem->event, 0) == WAIT_OBJECT_0) { XLockDisplay(subsystem->display); if (XEventsQueued(subsystem->display, QueuedAlready)) { XNextEvent(subsystem->display, &xevent); x11_shadow_handle_xevent(subsystem, &xevent); } XUnlockDisplay(subsystem->display); } if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime)) { x11_shadow_check_resize(subsystem); x11_shadow_screen_grab(subsystem); x11_shadow_query_cursor(subsystem, FALSE); dwInterval = 1000 / subsystem->captureFrameRate; frameTime += dwInterval; } } ExitThread(0); return NULL; }
/* * Input thread reading from device. * Generates events on incoming data. */ static void* x11EventThread( DirectThread *thread, void *driver_data ) { X11InputData *data = driver_data; DFBX11 *x11 = data->x11; DFBX11Shared *shared = x11->shared; while (!data->stop) { unsigned int pull = 23; XEvent xEvent; DFBInputEvent dfbEvent; static int nextKeyIsRepeat = false; /* FIXME: Detect key repeats, we're receiving KeyPress, KeyRelease, KeyPress, KeyRelease... !!?? */ if (shared->window == 0) { /* no window, so no event */ usleep( 50000 ); continue; } usleep( 10000 ); XLockDisplay( x11->display ); while (!data->stop && pull-- && XPending( x11->display )) { XNextEvent( x11->display, &xEvent ); /* is this key repeat? idea from GII */ if ( (xEvent.type == KeyRelease) && (XPending( x11->display )) ) { XEvent peekEvent; XPeekEvent( x11->display, &peekEvent ); if ( (peekEvent.type == KeyPress) && (peekEvent.xkey.keycode == xEvent.xkey.keycode) && (peekEvent.xkey.time - xEvent.xkey.time < 2) ) { nextKeyIsRepeat = true; } } XUnlockDisplay( x11->display ); D_DEBUG_AT( X11_Input, "Event received: %d\n", xEvent.type ); switch (xEvent.type) { case ButtonPress: case ButtonRelease: motion_realize( data ); case MotionNotify: handleMouseEvent( &xEvent, data ); // crash ??? break; case KeyPress: case KeyRelease: { motion_realize( data ); dfbEvent.type = (xEvent.type == KeyPress) ? DIET_KEYPRESS : DIET_KEYRELEASE; dfbEvent.flags = DIEF_KEYCODE | DIEF_TIMESTAMP; dfbEvent.key_code = xEvent.xkey.keycode; dfbEvent.timestamp.tv_sec = xEvent.xkey.time / 1000; dfbEvent.timestamp.tv_usec = (xEvent.xkey.time % 1000) * 1000; if ( (xEvent.type == KeyPress) && nextKeyIsRepeat ) { nextKeyIsRepeat = false; dfbEvent.flags |= DIEF_REPEAT; } dfb_input_dispatch( data->device, &dfbEvent ); break; } case Expose: //handle_expose( &xEvent.xexpose ); break; case DestroyNotify: /* this event is mainly to unblock XNextEvent. */ break; default: break; } XLockDisplay( x11->display ); } XUnlockDisplay( x11->display ); if (!data->stop) motion_realize( data ); } return NULL; }