int wsGetDepthOnScreen(void) { int depth; XImage *mXImage; Visual *visual; if ((depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, &visual)) > 0) { mXImage = XCreateImage(wsDisplay, visual, depth, ZPixmap, 0, NULL, 1, 1, 32, 0); wsDepthOnScreen = mXImage->bits_per_pixel; wsRedMask = mXImage->red_mask; wsGreenMask = mXImage->green_mask; wsBlueMask = mXImage->blue_mask; #if HAVE_BIGENDIAN wsNonNativeOrder = mXImage->byte_order == LSBFirst; #else wsNonNativeOrder = mXImage->byte_order == MSBFirst; #endif XDestroyImage(mXImage); } else { int bpp, ibpp; XWindowAttributes attribs; mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); bpp = mXImage->bits_per_pixel; XGetWindowAttributes(wsDisplay, wsRootWin, &attribs); ibpp = attribs.depth; mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); bpp = mXImage->bits_per_pixel; if ((ibpp + 7) / 8 != (bpp + 7) / 8) ibpp = bpp; wsDepthOnScreen = ibpp; wsRedMask = mXImage->red_mask; wsGreenMask = mXImage->green_mask; wsBlueMask = mXImage->blue_mask; XDestroyImage(mXImage); } return wsDepthOnScreen; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { // int screen; // int interval, prefer_blank, allow_exp, nothing; Colormap theCmap; const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt; #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; #endif Flip_Flag = flags & VOFLAG_FLIPPING; zoomFlag = flags & VOFLAG_SWSCALE; old_vo_dwidth = -1; old_vo_dheight = -1; int_pause = 0; if (!title) title = "MPlayer X11 (XImage/Shm) render"; in_format = format; srcW = width; srcH = height; XGetWindowAttributes(mDisplay, mRootWin, &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) { Visual *visual; depth = vo_find_depth_from_visuals(mDisplay, mScreen, &visual); } if (!XMatchVisualInfo(mDisplay, mScreen, depth, DirectColor, &vinfo) || (WinID > 0 && vinfo.visualid != XVisualIDFromVisual(attribs.visual))) XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); /* set image size (which is indeed neither the input nor output size), if zoom is on it will be changed during draw_slice anyway so we don't duplicate the aspect code here */ image_width = (width + 7) & (~7); image_height = height; { #ifdef CONFIG_XF86VM if (vm) { vo_vm_switch(); } #endif theCmap = vo_x11_create_colormap(&vinfo); vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, vo_dwidth, vo_dheight, flags, theCmap, "x11", title); if (WinID > 0) depth = vo_x11_update_geometry(); #ifdef CONFIG_XF86VM if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) XGrabPointer(mDisplay, vo_window, True, 0, GrabModeAsync, GrabModeAsync, vo_window, None, CurrentTime); XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); } #endif } if (myximage) { freeMyXImage(); sws_freeContext(swsContext); } getMyXImage(); while (fmte->mpfmt) { int depth = IMGFMT_RGB_DEPTH(fmte->mpfmt); /* bits_per_pixel in X seems to be set to 16 for 15 bit formats => force depth to 16 so that only the color masks are used for the format check */ if (depth == 15) depth = 16; if (depth == myximage->bits_per_pixel && fmte->byte_order == myximage->byte_order && fmte->red_mask == myximage->red_mask && fmte->green_mask == myximage->green_mask && fmte->blue_mask == myximage->blue_mask) break; fmte++; } if (!fmte->mpfmt) { mp_msg(MSGT_VO, MSGL_ERR, "X server image format not supported, please contact the developers\n"); return -1; } out_format = fmte->mpfmt; switch ((bpp = myximage->bits_per_pixel)) { case 24: draw_alpha_fnc = draw_alpha_24; break; case 32: draw_alpha_fnc = draw_alpha_32; break; case 15: case 16: if (depth == 15) draw_alpha_fnc = draw_alpha_15; else draw_alpha_fnc = draw_alpha_16; break; default: draw_alpha_fnc = draw_alpha_null; } out_offset = 0; // for these formats conversion is currently not support and // we can easily "emulate" them. if (out_format & 64 && (IMGFMT_IS_RGB(out_format) || IMGFMT_IS_BGR(out_format))) { out_format &= ~64; #if HAVE_BIGENDIAN out_offset = 1; #else out_offset = -1; #endif } /* always allocate swsContext as size could change between frames */ swsContext = sws_getContextFromCmdLine(width, height, in_format, width, height, out_format); if (!swsContext) return -1; dst_width = width; //printf( "X11 bpp: %d color mask: R:%lX G:%lX B:%lX\n",bpp,myximage->red_mask,myximage->green_mask,myximage->blue_mask ); return 0; }
static int config(struct vo *vo, uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, uint32_t format) { struct priv *p = vo->priv; Colormap theCmap; const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt; #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; #endif p->Flip_Flag = flags & VOFLAG_FLIPPING; p->zoomFlag = 1; p->old_vo_dwidth = -1; p->old_vo_dheight = -1; p->in_format = format; p->srcW = width; p->srcH = height; XGetWindowAttributes(vo->x11->display, vo->x11->rootwin, &p->attribs); p->depth = p->attribs.depth; if (p->depth != 15 && p->depth != 16 && p->depth != 24 && p->depth != 32) { Visual *visual; p->depth = vo_find_depth_from_visuals(vo->x11->display, vo->x11->screen, &visual); } if (!XMatchVisualInfo(vo->x11->display, vo->x11->screen, p->depth, DirectColor, &p->vinfo) || (WinID > 0 && p->vinfo.visualid != XVisualIDFromVisual(p->attribs.visual))) { XMatchVisualInfo(vo->x11->display, vo->x11->screen, p->depth, TrueColor, &p->vinfo); } /* set image size (which is indeed neither the input nor output size), if zoom is on it will be changed during draw_slice anyway so we don't duplicate the aspect code here */ p->image_width = (width + 7) & (~7); p->image_height = height; { #ifdef CONFIG_XF86VM if (vm) vo_vm_switch(vo); #endif theCmap = vo_x11_create_colormap(vo, &p->vinfo); vo_x11_create_vo_window(vo, &p->vinfo, vo->dx, vo->dy, vo->dwidth, vo->dheight, flags, theCmap, "x11"); if (WinID > 0) p->depth = vo_x11_update_geometry(vo, true); #ifdef CONFIG_XF86VM if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) XGrabPointer(vo->x11->display, vo->x11->window, True, 0, GrabModeAsync, GrabModeAsync, vo->x11->window, None, CurrentTime); XSetInputFocus(vo->x11->display, vo->x11->window, RevertToNone, CurrentTime); } #endif } if (p->myximage) { freeMyXImage(p); sws_freeContext(p->swsContext); } getMyXImage(p); while (fmte->mpfmt) { int depth = IMGFMT_RGB_DEPTH(fmte->mpfmt); /* bits_per_pixel in X seems to be set to 16 for 15 bit formats => force depth to 16 so that only the color masks are used for the format check */ if (depth == 15) depth = 16; if (depth == p->myximage->bits_per_pixel && fmte->byte_order == p->myximage->byte_order && fmte->red_mask == p->myximage->red_mask && fmte->green_mask == p->myximage->green_mask && fmte->blue_mask == p->myximage->blue_mask) break; fmte++; } if (!fmte->mpfmt) { mp_msg( MSGT_VO, MSGL_ERR, "X server image format not supported, please contact the developers\n"); return -1; } p->out_format = fmte->mpfmt; p->bpp = p->myximage->bits_per_pixel; p->out_offset = 0; // We can easily "emulate" non-native RGB32 and BGR32 if (p->out_format == (IMGFMT_BGR32 | 128) || p->out_format == (IMGFMT_RGB32 | 128)) { p->out_format &= ~128; #if BYTE_ORDER == BIG_ENDIAN p->out_offset = 1; #else p->out_offset = -1; #endif } /* always allocate swsContext as size could change between frames */ p->swsContext = sws_getContextFromCmdLine(width, height, p->in_format, width, height, p->out_format); if (!p->swsContext) return -1; p->dst_width = width; return 0; }
void wsCreateWindow(wsTWindow *win, int X, int Y, int wX, int hY, int bW, int cV, unsigned char D, char *label) { int depth; win->Property = D; if (D & wsShowFrame) win->Decorations = 1; wsHGC = DefaultGC(wsDisplay, wsScreen); // The window position and size. switch (X) { case -1: win->X = (wsMaxX / 2) - (wX / 2) + wsOrgX; break; case -2: win->X = wsMaxX - wX - 1 + wsOrgX; break; default: win->X = X; break; } switch (Y) { case -1: win->Y = (wsMaxY / 2) - (hY / 2) + wsOrgY; break; case -2: win->Y = wsMaxY - hY - 1 + wsOrgY; break; default: win->Y = Y; break; } win->Width = wX; win->Height = hY; win->OldX = win->X; win->OldY = win->Y; win->OldWidth = win->Width; win->OldHeight = win->Height; // Border size for window. win->BorderWidth = bW; // Hide Mouse Cursor win->wsCursor = None; win->wsMouseEventType = cV; win->wsCursorData[0] = 0; win->wsCursorPixmap = XCreateBitmapFromData(wsDisplay, wsRootWin, win->wsCursorData, 1, 1); if (!(cV & wsShowMouseCursor)) win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0); depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, NULL); if (depth < 15) { mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ColorDepthTooLow); guiExit(EXIT_ERROR); } XMatchVisualInfo(wsDisplay, wsScreen, depth, TrueColor, &win->VisualInfo); // --- win->AtomLeaderClient = XInternAtom(wsDisplay, "WM_CLIENT_LEADER", False); win->AtomDeleteWindow = XInternAtom(wsDisplay, "WM_DELETE_WINDOW", False); win->AtomTakeFocus = XInternAtom(wsDisplay, "WM_TAKE_FOCUS", False); win->AtomRolle = XInternAtom(wsDisplay, "WM_WINDOW_ROLE", False); win->AtomWMSizeHint = XInternAtom(wsDisplay, "WM_SIZE_HINT", False); win->AtomWMNormalHint = XInternAtom(wsDisplay, "WM_NORMAL_HINT", False); win->AtomProtocols = XInternAtom(wsDisplay, "WM_PROTOCOLS", False); win->AtomsProtocols[0] = win->AtomDeleteWindow; win->AtomsProtocols[1] = win->AtomTakeFocus; win->AtomsProtocols[2] = win->AtomRolle; // --- win->WindowAttrib.background_pixel = BlackPixel(wsDisplay, wsScreen); win->WindowAttrib.border_pixel = WhitePixel(wsDisplay, wsScreen); win->WindowAttrib.colormap = XCreateColormap(wsDisplay, wsRootWin, win->VisualInfo.visual, AllocNone); win->WindowAttrib.event_mask = StructureNotifyMask | FocusChangeMask | ExposureMask | PropertyChangeMask | EnterWindowMask | LeaveWindowMask | VisibilityChangeMask | KeyPressMask | KeyReleaseMask; if ((cV & wsHandleMouseButton)) win->WindowAttrib.event_mask |= ButtonPressMask | ButtonReleaseMask; if ((cV & wsHandleMouseMove)) win->WindowAttrib.event_mask |= PointerMotionMask; win->WindowAttrib.cursor = win->wsCursor; win->WindowAttrib.override_redirect = False; if (D & wsOverredirect) win->WindowAttrib.override_redirect = True; win->WindowMask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect; win->WindowID = XCreateWindow(wsDisplay, (win->Parent != 0 ? win->Parent : wsRootWin), win->X, win->Y, win->Width, win->Height, win->BorderWidth, win->VisualInfo.depth, InputOutput, win->VisualInfo.visual, win->WindowMask, &win->WindowAttrib); wsClassHint.res_name = "MPlayer"; wsClassHint.res_class = "MPlayer"; XSetClassHint(wsDisplay, win->WindowID, &wsClassHint); win->SizeHint.flags = PPosition | PSize | PResizeInc | PWinGravity; // | PBaseSize; win->SizeHint.x = win->X; win->SizeHint.y = win->Y; win->SizeHint.width = win->Width; win->SizeHint.height = win->Height; if (D & wsMinSize) { win->SizeHint.flags |= PMinSize; win->SizeHint.min_width = win->Width; win->SizeHint.min_height = win->Height; } if (D & wsMaxSize) { win->SizeHint.flags |= PMaxSize; win->SizeHint.max_width = win->Width; win->SizeHint.max_height = win->Height; } win->SizeHint.height_inc = 1; win->SizeHint.width_inc = 1; win->SizeHint.base_width = win->Width; win->SizeHint.base_height = win->Height; win->SizeHint.win_gravity = StaticGravity; XSetWMNormalHints(wsDisplay, win->WindowID, &win->SizeHint); win->WMHints.flags = InputHint | StateHint; win->WMHints.input = True; win->WMHints.initial_state = NormalState; XSetWMHints(wsDisplay, win->WindowID, &win->WMHints); wsWindowDecoration(win, win->Decorations); XStoreName(wsDisplay, win->WindowID, label); XmbSetWMProperties(wsDisplay, win->WindowID, label, label, NULL, 0, NULL, NULL, NULL); XSetWMProtocols(wsDisplay, win->WindowID, win->AtomsProtocols, 3); XChangeProperty(wsDisplay, win->WindowID, win->AtomLeaderClient, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&LeaderWindow, 1); wsTextProperty.value = label; wsTextProperty.encoding = XA_STRING; wsTextProperty.format = 8; wsTextProperty.nitems = strlen(label); XSetWMIconName(wsDisplay, win->WindowID, &wsTextProperty); win->wGC = XCreateGC(wsDisplay, win->WindowID, GCForeground | GCBackground, &win->wGCV); win->Visible = 0; win->Focused = 0; win->Mapped = 0; win->Rolled = 0; if (D & wsShowWindow) XMapWindow(wsDisplay, win->WindowID); wsCreateImage(win, win->Width, win->Height); // --- End of creating -------------------------------------------------------------------------- { int i; for (i = 0; i < wsWLCount; i++) if (wsWindowList[i] == NULL) break; if (i == wsWLCount) { mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_TooManyOpenWindows); guiExit(EXIT_ERROR); } wsWindowList[i] = win; } XFlush(wsDisplay); XSync(wsDisplay, False); win->ReDraw = NULL; win->ReSize = NULL; win->Idle = NULL; win->MouseHandler = NULL; win->KeyHandler = NULL; mp_dbg(MSGT_GPLAYER, MSGL_DBG2, "[ws] window is created. ( %s ).\n", label); }
// ---------------------------------------------------------------------------------------------- // wsWindowCreate: create a new window on the screen. // x,y : window position // w,h : window size // c : mouse cursor visible // p : properties - "decoration", visible titlebar, etc ... // ---------------------------------------------------------------------------------------------- void wsWindowCreate(wsWindow *win, int x, int y, int w, int h, int p, int c, char *label) { int depth; win->Property = p; win->Decoration = ((p & wsShowFrame) != 0); wsWindowUpdatePosition(win, x, y, w, h); win->Width = w; win->Height = h; win->OldX = win->X; win->OldY = win->Y; win->OldWidth = win->Width; win->OldHeight = win->Height; /* Hide Mouse Cursor */ win->wsCursor = None; win->wsMouseEventType = c; win->wsCursorData[0] = 0; win->wsCursorPixmap = XCreateBitmapFromData(wsDisplay, wsRootWin, win->wsCursorData, 1, 1); if (!(c & wsShowMouseCursor)) win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0); depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, NULL); if (depth < 15) { mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ColorDepthTooLow); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } XMatchVisualInfo(wsDisplay, wsScreen, depth, TrueColor, &win->VisualInfo); /* --- */ win->AtomLeaderClient = XInternAtom(wsDisplay, "WM_CLIENT_LEADER", False); win->AtomDeleteWindow = XInternAtom(wsDisplay, "WM_DELETE_WINDOW", False); win->AtomTakeFocus = XInternAtom(wsDisplay, "WM_TAKE_FOCUS", False); win->AtomRolle = XInternAtom(wsDisplay, "WM_WINDOW_ROLE", False); win->AtomWMSizeHint = XInternAtom(wsDisplay, "WM_SIZE_HINT", False); win->AtomWMNormalHint = XInternAtom(wsDisplay, "WM_NORMAL_HINT", False); win->AtomProtocols = XInternAtom(wsDisplay, "WM_PROTOCOLS", False); win->AtomsProtocols[0] = win->AtomDeleteWindow; win->AtomsProtocols[1] = win->AtomTakeFocus; win->AtomsProtocols[2] = win->AtomRolle; /* --- */ win->WindowAttrib.border_pixel = WhitePixel(wsDisplay, wsScreen); win->WindowAttrib.colormap = XCreateColormap(wsDisplay, wsRootWin, win->VisualInfo.visual, AllocNone); win->WindowAttrib.event_mask = StructureNotifyMask | FocusChangeMask | ExposureMask | PropertyChangeMask | EnterWindowMask | LeaveWindowMask | VisibilityChangeMask | KeyPressMask | KeyReleaseMask; if ((c & wsHandleMouseButton)) win->WindowAttrib.event_mask |= ButtonPressMask | ButtonReleaseMask; if ((c & wsHandleMouseMove)) win->WindowAttrib.event_mask |= PointerMotionMask; win->WindowAttrib.cursor = win->wsCursor; win->WindowAttrib.override_redirect = False; if (p & wsOverredirect) win->WindowAttrib.override_redirect = True; win->WindowMask = CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect; win->WindowID = XCreateWindow(wsDisplay, (win->Parent != 0 ? win->Parent : wsRootWin), win->X, win->Y, win->Width, win->Height, 0, win->VisualInfo.depth, InputOutput, win->VisualInfo.visual, win->WindowMask, &win->WindowAttrib); wsClassHint.res_name = "MPlayer"; wsClassHint.res_class = "MPlayer"; XSetClassHint(wsDisplay, win->WindowID, &wsClassHint); wsWindowSizeHint(win); win->WMHints.flags = InputHint | StateHint; win->WMHints.input = True; win->WMHints.initial_state = NormalState; XSetWMHints(wsDisplay, win->WindowID, &win->WMHints); wsWindowDecoration(win); XStoreName(wsDisplay, win->WindowID, label); XmbSetWMProperties(wsDisplay, win->WindowID, label, label, NULL, 0, NULL, NULL, NULL); XSetWMProtocols(wsDisplay, win->WindowID, win->AtomsProtocols, 3); XChangeProperty(wsDisplay, win->WindowID, win->AtomLeaderClient, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&LeaderWindow, 1); wsTextProperty.value = label; wsTextProperty.encoding = XA_STRING; wsTextProperty.format = 8; wsTextProperty.nitems = strlen(label); XSetWMIconName(wsDisplay, win->WindowID, &wsTextProperty); win->wGC = XCreateGC(wsDisplay, win->WindowID, 0, NULL); win->Visible = wsNo; win->Focused = wsNo; win->Mapped = wsNo; win->Rolled = wsNo; if (p & wsShowWindow) { XMapWindow(wsDisplay, win->WindowID); wsWindowMapWait(win); } wsImageCreate(win, win->Width, win->Height); /* End of creating -------------------------------------------------------------------------- */ { int i; for (i = 0; i < wsWLCount; i++) if (wsWindowList[i] == NULL) break; if (i == wsWLCount) { mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_TooManyOpenWindows); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } wsWindowList[i] = win; } XFlush(wsDisplay); XSync(wsDisplay, False); win->DrawHandler = NULL; win->MouseHandler = NULL; win->KeyHandler = NULL; mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] window is created. ( %s ).\n", label); }