Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!atexnet!cvbnet!caribe.prime.com!aperez From: aperez@caribe.prime.com (Arturo Perez x6739) Newsgroups: comp.windows.x Subject: Long query about color XOR'ing Message-ID: <192@cvbnetPrime.COM> Date: 10 Apr 90 17:44:09 GMT Sender: postnews@cvbnetPrime.COM Reply-To: aperez@cvbnet.prime.com (Arturo Perez x6739) Distribution: na Organization: Prime Computervision, Bedford MA Lines: 148 I'm working on some code from xtank (to get it to work in color) and I'm running into something I don't understand. Could some kind soul out there explain what's happening? I'm running the MIT X server, release 4 with patches 1-9 installed on a sun 3/60 whose default visual is PseudoColor. The xtank game creates scads of GC's, one for every combination color, operation, and font. That turns out to be about 100 GC's. There also seems to be quite a lot of bitmaps, possibly as many as 350. That's just for background. There are 2 modes of operation, GXxor and GXcopy. The GXxor operation is used for most of the drawing operations involving the bitmaps, in order to draw, erase, move, draw the bitmaps. Originally, the code looked like this: for(i = 0 ; i < MAX_COLORS ; i++) { for(j = 0 ; j < MAX_DRAW_FUNCS ; j++) { switch(j) { case DRAW_XOR: values.function = GXxor; values.background = vid->bg; values.foreground = vid->color[i] ^ vid->fg; And to draw a bitmap, like so: #define draw_picture(w,x,y,pic,func,_color) \ { \ int tmp_x = x - pic->offset_x; \ int tmp_y = y - pic->offset_y; \ if(x > -pic->offset_x && tmp_x < vid->win[w].width && \ y > -pic->offset_y && tmp_y < vid->win[w].height) { \ if(vid->planes == 1)\ XCopyArea(vid->dpy,vid->pixid[pic->pixmap],vid->win[w].id, \ vid->graph_gc[func][_color],0,0,pic->width,pic->height, \ tmp_x,tmp_y); \ else\ XCopyPlane(vid->dpy,vid->pixid[pic->pixmap],vid->win[w].id, \ vid->graph_gc[func][_color],0,0,pic->width,pic->height, \ tmp_x,tmp_y, 1);\ }\ } And that didn't work. All I got were white blocks instead of the bitmaps. Now, on a PseudoColor screen, this is obviously wrong because we're dealing with colormap entries, not pixel values. So, I changed it to this: for(i = 0 ; i < MAX_COLORS ; i++) { for(j = 0 ; j < MAX_DRAW_FUNCS ; j++) { switch(j) { case DRAW_XOR: values.function = GXxor; values.background = vid->bg; values.foreground = vid->color[i]; And that didn't work. The bitmaps came out correctly, but lines and text did not. The lines and text didn't come out at all, as a matter of fact. Also, in mono the bitmaps came out fine, but on a color screen the bitmaps came out in reverse, i.e. black on white, instead of white on black. This is background for my first bunch of questions. How come lines didn't come out when I`m using the GC for xor? All I'm doing is using it in an XDrawLine request. Why do the bitmaps come out as black on white on a color screen? So, next I try: for(i = 0 ; i < MAX_COLORS ; i++) { for(j = 0 ; j < MAX_DRAW_FUNCS ; j++) { switch(j) { case DRAW_XOR: values.function = GXxor; values.background = vid->color[i]; values.foreground = vid->bg; And that works perfectly in mono but in color the bitmaps come in in black with a colored box surrounding them. Why the difference? I would have thought that if the bitmap looked fine in mono, it should have looked fine in color as well. So, then I changed it to: for(i = 0 ; i < MAX_COLORS ; i++) { for(j = 0 ; j < MAX_DRAW_FUNCS ; j++) { switch(j) { case DRAW_XOR: values.function = GXxor; if (vid->color[i] == vid->fg) { values.background = vid->fg; values.foreground = vid->bg; } else { values.background = vid->fg; values.foreground = vid->color[i]; } And this sort of works for both color and black/white. At least, the bitmaps come out color on black and white on black. But, out of the set of colors Black, White, Red, Orange, Yellow, Green, Blue and Violet on my workstation (3/60 /dev/cgfour0) the orange comes out as dark blue and the blue and violet don't come out at all, that is, the bitmaps drawn in those 2 colors are invisible. Even worse, on other workstations (even other 3/60) none of the colors look correct. Why do the colors look right on my machine but no one else's? Why don`t the colors come out right if I XOR them onto black? I reason, probably incorrectly, that the colors are behaving as if they were being XOR'ed onto white. So, I change the draw_picture macro to #define draw_picture(w,x,y,pic,func,_color) \ { \ int tmp_x = x - pic->offset_x; \ int tmp_y = y - pic->offset_y; \ if(x > -pic->offset_x && tmp_x < vid->win[w].width && \ y > -pic->offset_y && tmp_y < vid->win[w].height) { \ if(vid->planes == 1)\ XCopyArea(vid->dpy,vid->pixid[pic->pixmap],vid->win[w].id, \ vid->graph_gc[func][_color],0,0,pic->width,pic->height, \ tmp_x,tmp_y); \ else\ switch(func) {\ case DRAW_XOR : \ if (_color != WHITE)\ XCopyPlane(vid->dpy,vid->pixid[pic->pixmap],vid->win[w].id,\ vid->graph_gc[func][WHITE],0,0,pic->width,pic->height, \ tmp_x,tmp_y, 1);\ case DRAW_COPY : \ XCopyPlane(vid->dpy,vid->pixid[pic->pixmap],vid->win[w].id, \ vid->graph_gc[func][_color],0,0,pic->width,pic->height, \ tmp_x,tmp_y, 1);\ }\ } \ } And everything looks correct, in both color and mono. And I've just converted the program into a real pig because CopyPlane has gotta be one of the most expensive Xlib calls. Why doesn't the vanilla XOR work? Is there a more efficient way to get the d****d bitmaps up on the screen in the correct color? Arturo Perez ComputerVision, a division of Prime aperez@cvbnet.prime.com Too much information, like a bullet through my brain -- The Police