コード例 #1
0
ファイル: ws.c プロジェクト: JasonFengIce/mplayer-android
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;
}
コード例 #2
0
ファイル: vo_x11.c プロジェクト: JasonFengIce/mplayer-android
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;
}
コード例 #3
0
ファイル: vo_x11.c プロジェクト: kax4/mpv
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;
}
コード例 #4
0
ファイル: ws.c プロジェクト: JasonFengIce/mplayer-android
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);
}
コード例 #5
0
ファイル: ws.c プロジェクト: jlelli/mplayer-dl
// ----------------------------------------------------------------------------------------------
//  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);
}