2014-07-20 1 views
0

응용 프로그램에 XFT를 사용하려고했지만 두 번째로 새 디스플레이로 텍스트를 그리려고하면 충돌이 발생합니다 동일한 프로세스 내부의 연결. 다음은 유스 케이스의 단순화 된 버전입니다. XFT 글꼴을 사용하여 동일한 응용 프로그램 프로세스에서 새 디스플레이 연결로 텍스트를 그릴 때 오류가 발생합니다.

while true 
do 
    OpenDisplay 
    LoadFont 
    Draw Text 
    Close Font 
    Close Display 
end 

나는 XCloseDisplay 또한 글꼴을 닫습니다 몇 포럼에서 읽을 수 있지만 내가 여러 글꼴로드 것을 시도 할 때 나는 메모리 누수를 발견했습니다.

내가 문제를 디버깅하기 위해 노력하고 이러한 나의 관찰,

  1. 코멘트 XftDrawText가 있었다, 충돌이
  2. 코멘트 XftFontClose가, 충돌이 사라 사라하지만 여기에 메모리를

누수 코드입니다 I 이것을 재현하는 데 사용됩니다. 어떤 도움을 주시면 감사하겠습니다.

#include <X11/Xlib.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <cstring> 
#include <iostream> 
#include <X11/Xft/Xft.h> 

using namespace std; 

const char fontNames[5][50] = { "helvetica", "arial", "courier", "times", "utopia" }; 
int sizes[5] = {10, 20, 30, 40, 50}; 
int numFonts = 5; 

void TestXft(Display* display, Window& win, GC& gc, const char *fontName, int size); 

Window create_simple_window(Display* display, int width, int height, int x, int y) 
{ 
    int screen_num = DefaultScreen(display); 
    int win_border_width = 2; 
    Window win; 
    win = XCreateSimpleWindow(display, RootWindow(display, screen_num), x, y, 
      width, height, win_border_width, 
      BlackPixel(display, screen_num), 
      WhitePixel(display, screen_num)); 

    XMapWindow(display, win); 

    XFlush(display); 

    return win; 
} 

GC create_gc(Display* display, Window win) 
{ 
    GC gc; 
    unsigned long valuemask = 0; 
    XGCValues values; 

    gc = XCreateGC(display, win, valuemask, &values); 

    if (gc < 0) 
    { 
     fprintf(stderr, "XCreateGC: \n"); 
    } 
    return gc; 
} 

int main(int argc, char* argv[]) 
{ 
    int screen_num; 
    Window win; 
    unsigned int display_width, display_height; 
    GC gc; 
    unsigned long count = 0; 

    while(true) 
    {  
     cout << "\nIteration: " << ++count << endl; 

     Display* display = XOpenDisplay(NULL); 
     if (display == NULL) 
     { 
      printf("Cannot connect to X server\n"); 
      exit(1); 
     } 

     screen_num = DefaultScreen(display); 
     display_width = 500; 
     display_height = 500; 

     win = create_simple_window(display, display_width, display_height, 0, 0); 
     XMapWindow(display, win); 

     XMoveWindow(display, win, 1000, 600); 

     gc = create_gc(display, win); 

     for(int i = 0; i < numFonts; i++) 
     { 
      TestXft(display, win, gc, fontNames[i], sizes[i]); 
     } 

     XUnmapWindow(display, win); 
     XFreeGC(display, gc); 
     XSync(display, false); 
     XCloseDisplay(display); 
    } 
    return 0; 
} 

void TestXft(Display* display, Window& win, GC& gc, const char *fontName, int size) 
{ 
    XftFont  *font = NULL; 
    XftDraw  *xftdraw = NULL; 
    XRenderColor xrcolor; 
    XftColor  xftcolor; 
    font = NULL; 

    Colormap colormap = XCreateColormap(display, win, DefaultVisual(display, DefaultScreen(display)), AllocNone); 

    font = XftFontOpen(display, DefaultScreen(display), XFT_FAMILY, XftTypeString, fontName, 
           XFT_SIZE, XftTypeDouble, (double) size, 
           XFT_SCALE, XftTypeDouble, 2.0, 
           NULL); 
    if (!font) 
    { 
     printf("Font not Found.\n"); 
     return; 
    } 

    xftdraw = XftDrawCreate(display, win, DefaultVisual(display,0), colormap); 

    xrcolor.red = 65535; 
    xrcolor.green= 0; 
    xrcolor.blue = 0; 
    xrcolor.alpha= 65535; 
    XftColorAllocValue(display, DefaultVisual(display,0), colormap, &xrcolor, &xftcolor); 

    const char *text = "RCB...RCB...RCB"; 
    XftDrawString8(xftdraw, &xftcolor, font, 200, 300 , (XftChar8 *) text, strlen(text)); 

    XftColorFree(display, DefaultVisual(display,0), colormap, &xftcolor); 
    XftDrawDestroy(xftdraw); 
    XftFontClose(display, font); 
    XFreeColormap(display, colormap); 
} 

답변

0

Xft 라이브러리의 버그로, 여러 번 열거 나 닫을 때 유용하지 않습니다.

XOpenDisplayXCloseDisplay을 루프 밖으로 이동하면 XDestroyWindow에 대한 호출을 추가하면 제대로 작동합니다.

관련 문제