Я пытаюсь нарисовать растровое изображение, чтобы позже скопировать его в окно. Я делаю это из Standard ML, используя PolyWW XWindows / Motif.
Приблизительно следуя инструкциям Найя в C, мой код не выполнялся в 20-50% случаев. В качестве обходного пути я вставил XFlushes не только после каждого X-вызова, но и в начале любой функции. При этом программа с моими основными вызовами рисования успешно работает не менее 20 раз подряд. Однако добавление одного вызова XFillRectangle для очистки фона вновь приводит к моей первоначальной проблеме, и код выполняется всего 4 раза из 5 или менее.
Код сводится к следующему примеру. Проблемной частью c является вызов XFillRectangle. Без этого программа запускается после компиляции не менее 20 раз. включая его, он дает сбой 20% или более раз и не попадает в функцию set с отладочным сообщением «copy».
open XWindows;
open Motif;
val testWindow = fn () =>
let
val rep = Option.valOf (Int.fromString (hd (CommandLine.arguments ())) );
val dim = {tw=400,th=400}
val shell = XtAppInitialise "" "test" "top" [] [ XmNwidth (#tw dim), XmNheight (#th dim) ] ;
val dp = XtDisplay shell;
val xf = XFlush ;
val main = XmCreateMainWindow shell "main" [ XmNmappedWhenManaged true ] ;
val canvas = XmCreateDrawingArea main "drawhere" [ XmNwidth (#tw dim), XmNheight (#th dim) ] ;
val usegc = DefaultGC (XtDisplay canvas) ;
val buf = XCreatePixmap (RootWindow dp) (Area{x=0,y=0,w = #tw dim, h= #th dim}) 24 ;
fun text1 n = ( xf dp ; XDrawArc buf usegc (XArc (Area{x=10,y=10,w = #tw dim -20 , h= #th dim -20} , 0,360*64 ));
xf dp ) ;
val _ = ( xf dp; XSetForeground usegc 0x098809 ;xf dp;
(* 20 % crash => *) xf dp ; XFillRectangle buf usegc (Area{x=0,y=0,w = #tw dim, h= #th dim}) ; xf dp;
List.app text1 (List.tabulate (rep ,fn i=> i)) ; xf dp;
print "done" ) ;
val set = fn (w,c,t) =>(xf dp ;
print "copy " ; TextIO.flushOut;
XCopyArea buf (XtWindow canvas) usegc ( XPoint {x=0,y=0} ) (Area{x=0,y=0,w = #tw dim , h= #th dim });
xf dp; t )
in
( XtSetCallbacks canvas [ (XmNexposeCallback , set) ] XmNarmCallback ;
XtManageChild canvas ;
XtManageChild main ;
XtRealizeWidget shell ;
xf dp ;
while (true) do (OS.Process.sleep (Time.fromReal 1.0))
)
end;
Мой вопрос: как это может быть? Или, скорее, как я могу подготовить Pixmap, которому нужно около 200 вызовов DrawAr c и фона, чтобы я мог скопировать его в окно позже ?? В растровом изображении все вызовы выполняются успешно, это обратный вызов set, который никогда не происходит.
Ошибки в основном являются одним из следующих 2:
shell$ ./demos 187
done[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
Assertion failed: (!xcb_xlib_threads_sequence_lost), function poll_for_event, file xcb_io.c, line 259.
shell$ ./demos 187
done
X Error BadIDChoice in XCreateWindow
XIO: fatal IO error 35 (Resource temporarily unavailable) on X server ":0"
after 360 requests (360 known processed) with 12 events remaining.
- update. Я полностью закодировал тот же пример в X Windows (без мотивов). Проблема сохраняется с более высокой частотой отказов.
- update 2. Я запрограммировал пример в C. Он не работает sh в том смысле, что я могу запустить его десятки раз без ошибок. Проблема должна исходить из того, как я использую X Windows или ML. Вот что я пытался сделать:
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
Display *display;
int screen_num;
void text1 (Pixmap buffer, GC gc, int n);
void _ (Pixmap buffer, GC gc, int n);
void set (Window win , Pixmap b, GC gc);
int main(int argc,char ** argv){
/* let */
int rep = atoi(argv[1]); /* need argument or will crash */
Window win;
unsigned int width=400, height=400;
int x=0, y=0;
unsigned int border_width = 0;
Pixmap buf;
int count;
XEvent report;
GC usegc;
char *display_name = NULL;
display=XOpenDisplay(display_name) ;
win = XCreateSimpleWindow(display, RootWindow(display,screen_num),
x, y, width, height, border_width, BlackPixel(display,
screen_num), WhitePixel(display,screen_num));
usegc=XCreateGC(display,win,0,NULL);
buf = XCreatePixmap ( display , RootWindow(display,screen_num) , 400,400,24) ;
_ (buf,usegc,rep);
/* in */
XSelectInput(display, win, ExposureMask );
XMapWindow(display, win);
while (1) {
XNextEvent(display, &report);
switch (report.type) {
case Expose:
set(win, buf,usegc);
break;
default:
break;
}
}
}
void text1 (Pixmap buffer, GC gc,int n) { XDrawArc( display, buffer, gc, 10,10,380,380, 0,360*64 ) ; }
void _ (Pixmap buffer, GC gc,int n)
{ XSetForeground(display , gc,16777215);
XFillRectangle(display,buffer,gc,0,0,400,400);
XSetForeground(display , gc,624649 );
for (int i=0;i<=n;i++)text1(buffer,gc,n);
}
void set(Window win, Pixmap b, GC gc){ XCopyArea (display,b,win,gc,0,0,400,400,0,0); }