price@Sun.COM (Chuck Price) (12/06/90)
You are not guaranteed that a particular X server will support arbitrary cursor sizes. (And I bet those that do support cursors the size of your window are not likely to move them around as quickly as you would hope). You will get quite reasonable performance on most systems by simulating a crosshair cursor on the client side. First, set an invisible cursor (makes any lag less noticable...). Next, be sure you are getting motion hints, not every mouse motion the server generates. Then listen for motion events, drawing and undrawing the lines with the appropriate graphics functions. This conference and the sources contain many examples of each step described above (check out most any window manager source). Also, using zero width lines frequently speeds things up quite a bit. -chuck
mouse@LIGHTNING.MCRCIM.MCGILL.EDU (12/06/90)
> I have the need for a very large crosshair cursor. By "very large" I > mean a crosshair cursor whose crosshairs always extend to the edge of > the window no matter how large the window is. This crosshair cursor > must also be clipped at the window boundaries so that the crosshairs > never extend outside the window. You cannot get these semantics by setting the cursor in the XDefineCursor sense; the X cursor mechanisms are incompatible with the goals you state. In particular, cursors are never clipped by window boundaries (the root window boundaries might be an exception). I fear you'll have to do your own crosshair drawing.... That said, let's try to see why your code doesn't work. I added a little code to turn it into a whole program, and here's what I'd say is going wrong: > /* how to tell if Create fails? */ > pix_curs = XCreatePixmap(disp, window, width, width, 1); > pix_curs_mask = XCreatePixmap(disp, window, width, width, 1); > tmp_gc = XCreateGC(disp, pix_curs, 0, NULL); If XCreatePixmap fails, you will get an error event (probably BadAlloc) from the server. If you don't arrange otherwise, this will print a message and kill your program. I notice that you don't clear pix_curs and pix_curs_mask. The initial contents of pixmaps are unspecified, and most servers use whatever junk happens to be lying around in the newly-allocated memory. Let's clear them first: XSetForeground(disp,tmp_gc,0L); XFillRectangle(disp,pix_curs,tmp_gc,0,0,width,width); XFillRectangle(disp,pix_curs_mask,tmp_gc,0,0,width,width); Ah. That got rid of the garbage. Now we just have a solid rectangle of the background color as the cursor. > [...set crosshair_lines[]...] > XDrawSegments (disp, pix_curs, tmp_gc, crosshair_lines, 2); Ah yes, the XSetForeground above changed the GC's foreground from the default of 1. Let's set it back (insert this before the XDrawSegments call): XSetForeground(disp,tmp_gc,1L); Now we have a solid rectangle of background with a vertical slit in it through which we see whatever's behind the cursor. > XSetFunction(disp, tmp_gc, GXcopyInverted); > XCopyArea(disp, pix_curs, pix_curs_mask, tmp_gc, 0, 0, width, width, > 0, 0); You've got this backwards. You want the mask to have 1 where the picture is to be visible and 0 where it is supposed to let the window(s) underneath it show through. Let's change the XSetFunction to set it to GXcopy, or, since that's the default and we haven't changed it yet, just delete the XSetFunction altogether. Ah. Now we have a T cross. Presumably what you were after is more like a + sign. To get that, change > crosshair_lines[0].y1 = crosshair_lines[0].y2 = 0; into crosshair_lines[0].y1 = crosshair_lines[0].y2 = width / 2; This produces a very nice crosshair. However, as I indicated above, it will ignore window boundaries. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
mouse@LARRY.MCRCIM.MCGILL.EDU (12/06/90)
> Well, first of all, you are not initializing your pixmap. This is true. > Also, you are not initializing your foreground in tmp_gc. This must > be set to 1 [...]. Also true. > Also, is it not an error to free the cursor before the window that is > using it is destroyed? I don't know but I am just wondering. It is not an error. From the Xlib document: 3.2. Window Attributes ... 3.2.10. Cursor Attribute The cursor attribute specifies which cursor is to be used when the pointer is in the InputOutput or InputOnly window. You can set the cursor to a cursor or None (default). If you set the cursor to None, the parent's cursor is used when the pointer is in the InputOutput or InputOnly window, and any change in the parent's cursor will cause an immedi- ate change in the displayed cursor. By calling XFreeCursor, the cursor can be freed immediately as long as no further explicit reference to it is made. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu