int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot) { int i; XcursorImage* native = XcursorImageCreate(image->width, image->height); if (native == NULL) return GL_FALSE; native->xhot = xhot; native->yhot = yhot; unsigned char* source = (unsigned char*) image->pixels; XcursorPixel* target = native->pixels; for (i = 0; i < image->width * image->height; i++, target++, source += 4) { *target = (source[3] << 24) | (source[0] << 16) | (source[1] << 8) | source[2]; } cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, native); XcursorImageDestroy(native); if (cursor->x11.handle == None) return GL_FALSE; return GL_TRUE; }
// Creates a native cursor object from the specified image and hotspot // Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) { int i; Cursor cursor; XcursorImage* native = XcursorImageCreate(image->width, image->height); if (native == NULL) return None; native->xhot = xhot; native->yhot = yhot; unsigned char* source = (unsigned char*) image->pixels; XcursorPixel* target = native->pixels; for (i = 0; i < image->width * image->height; i++, target++, source += 4) { *target = (source[3] << 24) | (source[0] << 16) | (source[1] << 8) | source[2]; } cursor = XcursorImageLoadCursor(_glfw.x11.display, native); XcursorImageDestroy(native); return cursor; }
// Creates a native cursor object from the specified image and hotspot // Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot) { int i; Cursor cursor; if (!_glfw.x11.xcursor.handle) return None; XcursorImage* native = XcursorImageCreate(image->width, image->height); if (native == NULL) return None; native->xhot = xhot; native->yhot = yhot; unsigned char* source = (unsigned char*) image->pixels; XcursorPixel* target = native->pixels; for (i = 0; i < image->width * image->height; i++, target++, source += 4) { unsigned int alpha = source[3]; *target = (alpha << 24) | ((unsigned char) ((source[0] * alpha) / 255) << 16) | ((unsigned char) ((source[1] * alpha) / 255) << 8) | ((unsigned char) ((source[2] * alpha) / 255) << 0); } cursor = XcursorImageLoadCursor(_glfw.x11.display, native); XcursorImageDestroy(native); return cursor; }
static Cursor X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y) { Display *display = GetDisplay(); Cursor cursor = None; XcursorImage *image; image = XcursorImageCreate(surface->w, surface->h); if (!image) { SDL_OutOfMemory(); return None; } image->xhot = hot_x; image->yhot = hot_y; image->delay = 0; SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); SDL_assert(surface->pitch == surface->w * 4); SDL_memcpy(image->pixels, surface->pixels, surface->h * surface->pitch); cursor = XcursorImageLoadCursor(display, image); XcursorImageDestroy(image); return cursor; }
ALLEGRO_MOUSE_CURSOR *_al_xwin_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); Display *xdisplay = system->x11display; int bmp_w; int bmp_h; ALLEGRO_MOUSE_CURSOR_XGLX *xcursor; XcursorImage *image; int c, ix, iy; bool was_locked; bmp_w = al_get_bitmap_width(bmp); bmp_h = al_get_bitmap_height(bmp); xcursor = al_malloc(sizeof *xcursor); if (!xcursor) { return NULL; } image = XcursorImageCreate(bmp->w, bmp->h); if (image == None) { al_free(xcursor); return NULL; } was_locked = al_is_bitmap_locked(bmp); if (!was_locked) { al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); } c = 0; for (iy = 0; iy < bmp_h; iy++) { for (ix = 0; ix < bmp_w; ix++) { ALLEGRO_COLOR col; unsigned char r, g, b, a; col = al_get_pixel(bmp, ix, iy); al_unmap_rgba(col, &r, &g, &b, &a); image->pixels[c++] = (a<<24) | (r<<16) | (g<<8) | (b); } } if (!was_locked) { al_unlock_bitmap(bmp); } image->xhot = x_focus; image->yhot = y_focus; _al_mutex_lock(&system->lock); xcursor->cursor = XcursorImageLoadCursor(xdisplay, image); _al_mutex_unlock(&system->lock); XcursorImageDestroy(image); return (ALLEGRO_MOUSE_CURSOR *)xcursor; }
void OS_X11::finalize() { if(main_loop) memdelete(main_loop); main_loop=NULL; spatial_sound_server->finish(); memdelete(spatial_sound_server); spatial_sound_2d_server->finish(); memdelete(spatial_sound_2d_server); //if (debugger_connection_console) { // memdelete(debugger_connection_console); //} #ifdef JOYDEV_ENABLED memdelete(joystick); #endif memdelete(input); memdelete(sample_manager); audio_server->finish(); memdelete(audio_server); visual_server->finish(); memdelete(visual_server); memdelete(rasterizer); physics_server->finish(); memdelete(physics_server); physics_2d_server->finish(); memdelete(physics_2d_server); XUnmapWindow( x11_display, x11_window ); XDestroyWindow( x11_display, x11_window ); #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) memdelete(context_gl); #endif for(int i=0;i<CURSOR_MAX;i++) { if( cursors[i] != None ) XFreeCursor( x11_display, cursors[i] ); if( img[i] != NULL ) XcursorImageDestroy( img[i] ); }; XDestroyIC( xic ); XCloseIM( xim ); XCloseDisplay(x11_display); if (xmbstring) memfree(xmbstring); args.clear(); }
QImage XCursorThemeData::loadImage (const QString &name, int size) const { if (size == -1) size = XcursorGetDefaultSize(QX11Info::display()); // Load the image XcursorImage *xcimage = xcLoadImage(name, size); if (!xcimage) xcimage = xcLoadImage(findAlternative(name), size); // Fall back to a legacy cursor //if (!xcimage) return LegacyTheme::loadImage(name); if (!xcimage) return QImage(); // Convert the XcursorImage to a QImage, and auto-crop it QImage image((uchar *)xcimage->pixels, xcimage->width, xcimage->height, QImage::Format_ARGB32_Premultiplied); image = autoCropImage(image); XcursorImageDestroy(xcimage); return image; }
CHwX11Cursor::~CHwX11Cursor(void) { for (std::vector<XcursorImage*>::iterator it=cimages.begin() ; it < cimages.end(); it++ ) XcursorImageDestroy(*it); cimages.clear(); if (cursor!=0) { SDL_SysWMinfo info; SDL_VERSION(&info.version); if (!SDL_GetWMInfo(&info)) { logOutput.Print("SDL error: can't get X11 window info"); return; } XFreeCursor(info.info.x11.display,cursor); } }
void cleanup () { if (wormy.cursor) { XFreeCursor (wormy.disp, wormy.cursor); wormy.cursor = 0; } if (wormy.xci) { XcursorImageDestroy(wormy.xci); wormy.xci = NULL; } int a; for (a = 0; a < 360; a++) if (wormy.cache[a]) { free(wormy.cache[a]); wormy.cache[a] = NULL; } memset(&wormy, 0, sizeof(wormy)); }
void PreviewCursor::cropCursorImage(XcursorImage *&image) const { // Calculate the auto-crop rectangle QRect r(QPoint(image->width, image->height), QPoint()); XcursorPixel *pixels = image->pixels; for(int y = 0; y < int(image->height); y++) { for(int x = 0; x < int(image->width); x++) { if(*(pixels++) >> 24) { if(x < r.left()) r.setLeft(x); if(x > r.right()) r.setRight(x); if(y < r.top()) r.setTop(y); if(y > r.bottom()) r.setBottom(y); } } } // Normalize the rectangle r = r.normalize(); // Don't crop the image if the size isn't going to change if(r.width() == int(image->width) && r.height() == int(image->height)) return; // Create the new image XcursorImage *cropped = XcursorImageCreate(r.width(), r.height()); XcursorPixel *src = image->pixels + r.top() * image->width + r.left(); XcursorPixel *dst = cropped->pixels; for(int y = 0; y < r.height(); y++, src += (image->width - r.width())) { for(int x = 0; x < r.width(); x++) { *(dst++) = *(src++); } } // Destroy the original XcursorImageDestroy(image); image = cropped; }
Bool apc_pointer_set_user( Handle self, Handle icon, Point hot_spot) { DEFXX; if ( XX-> user_pointer != None) { XFreeCursor( DISP, XX-> user_pointer); XX-> user_pointer = None; } if ( XX-> user_p_source != None) { XFreePixmap( DISP, XX-> user_p_source); XX-> user_p_source = None; } if ( XX-> user_p_mask != None) { XFreePixmap( DISP, XX-> user_p_mask); XX-> user_p_mask = None; } #ifdef HAVE_X11_XCURSOR_XCURSOR_H if ( XX-> user_xcursor != NULL) { XcursorImageDestroy(XX-> user_xcursor); XX-> user_xcursor = NULL; } #endif if ( icon != nilHandle) { Bool ok = create_cursor(self, icon, hot_spot); if ( !ok ) return false; if ( XX-> pointer_id == crUser && self != application) { if ( guts. pointer_invisible_count < 0) { if ( !XX-> flags. pointer_obscured) { XDefineCursor( DISP, XX-> udrawable, prima_null_pointer()); XX-> flags. pointer_obscured = 1; } } else { XDefineCursor( DISP, XX-> udrawable, XX-> user_pointer); XX-> flags. pointer_obscured = 0; } XCHECKPOINT; } } XFlush( DISP); if ( guts. grab_widget) apc_widget_set_capture( guts. grab_widget, true, guts. grab_confine); return true; }
static void setcursor(uint8_t * rgba, int16_t hotx, int16_t hoty) { XcursorImage * ci = XcursorImageCreate(32, 32); unsigned i; uint32_t * dst = (uint32_t*)ci->pixels; defaultcursor(); ci->xhot = hotx; ci->yhot = hoty; for (i = 0; i < 32*32; i++) dst[i] = 0 + (rgba[i*4+3] << 24) + (rgba[i*4+0] << 16) + (rgba[i*4+1] << 8) + (rgba[i*4+2] << 0) ; g_cursor = XcursorImageLoadCursor(g_dpy, ci); XDefineCursor(g_dpy, g_win, g_cursor); XcursorImageDestroy(ci); }
static Bool xcursor_load( Handle self, Handle icon) { DEFXX; int id; PIcon c; int x, y; XcursorPixel * src; XcursorImage* i; Byte * dst_data, * dst_mask; Bool kill; id = get_cursor( self, nil, nil, nil, nil); if ( id < crDefault || id > crUser) return false; if ( id != crUser ) { if (( i = XcursorLibraryLoadImage( xcursor_map[id] , NULL, guts. cursor_width )) == NULL) return false; kill = true; } else { i = XX-> user_xcursor; kill = false; } c = PIcon(icon); CIcon(icon)-> create_empty_icon( icon, i->width, i->height, imRGB, imbpp8); dst_data = c->data + c->lineSize * ( c-> h - 1 ); dst_mask = c->mask + c->maskLine * ( c-> h - 1 ); src = i->pixels; for ( y = 0; y < c-> h; y++) { Byte * d_data = dst_data, * d_mask = dst_mask; for ( x = 0; x < c-> w; x++) { *d_data++ = *src & 0xff; *d_data++ = (*src >> 8) & 0xff; *d_data++ = (*src >> 16) & 0xff; *d_mask++ = (*src >> 24) & 0xff; src++; } dst_mask -= c->maskLine; dst_data -= c->lineSize; } if ( kill ) XcursorImageDestroy(i); return true; }
static Cursor create_cursor_from_image_data_resource(Display *dpy, Window wnd, PP_Resource image_data, int hotspot_x, int hotspot_y) { struct pp_image_data_s *id = pp_resource_acquire(image_data, PP_RESOURCE_IMAGE_DATA); if (!id) { trace_warning("%s, bad resource\n", __func__); return None; } XcursorImage *cursor_image = XcursorImageCreate(id->width, id->height); cursor_image->xhot = hotspot_x; cursor_image->yhot = hotspot_y; memcpy(cursor_image->pixels, id->data, id->stride * id->height); Cursor cursor = XcursorImageLoadCursor(dpy, cursor_image); XcursorImageDestroy(cursor_image); pp_resource_release(image_data); return cursor; }
void CHwX11Cursor::resizeImage(XcursorImage*& image, const int new_x, const int new_y) { if (int(image->width) == new_x && int(image->height) == new_y) return; const int old_x = image->width; const int old_y = image->height; XcursorImage* new_image = XcursorImageCreate(new_x, new_y); new_image->delay = image->delay; const unsigned char* src = (unsigned char*)image->pixels; unsigned char* dst = (unsigned char*)new_image->pixels; memset(dst, 0, new_x*new_y*4); for (int y = 0; y < old_y; ++y) for (int x = 0; x < old_x; ++x) for (int v = 0; v < 4; ++v) dst[(y*new_x+x)*4+v] = src[(y*old_x+x)*4+v]; XcursorImageDestroy(image); image = new_image; }
QImage XCursorTheme::loadImage(const QString &name, int size) const { if (size <= 0) size = autodetectCursorSize(); // Load the image XcursorImage *xcimage = xcLoadImage(name, size); if (!xcimage) xcimage = xcLoadImage(findAlternative(name), size); if (!xcimage) { return QImage(); } // Convert the XcursorImage to a QImage, and auto-crop it QImage image((uchar *)xcimage->pixels, xcimage->width, xcimage->height, QImage::Format_ARGB32_Premultiplied ); image = autoCropImage(image); XcursorImageDestroy(xcimage); return image; }
static Bool create_cursor(Handle self, Handle icon, Point hot_spot) { #ifdef HAVE_X11_XCURSOR_XCURSOR_H DEFXX; XcursorImage* i; PIcon c = PIcon(icon); Bool kill; int x, y; XcursorPixel * dst; Byte * src_data, * src_mask; if ( hot_spot. x < 0) hot_spot. x = 0; if ( hot_spot. y < 0) hot_spot. y = 0; if ( hot_spot. x >= c-> w) hot_spot. x = c-> w - 1; if ( hot_spot. y >= c-> h) hot_spot. y = c-> h - 1; XX-> pointer_hot_spot = hot_spot; if (( i = XcursorImageCreate( c-> w, c-> h )) == NULL) { warn( "XcursorImageCreate(%d,%d) error", c->w, c->h); return false; } i-> xhot = hot_spot. x; i-> yhot = c-> h - hot_spot. y - 1; if ( c-> type != imRGB || c-> maskType != imbpp8 ) { icon = CIcon(icon)->dup(icon); kill = true; CIcon(icon)-> set_type( icon, imRGB ); CIcon(icon)-> set_maskType( icon, imbpp8 ); } else kill = false; c = PIcon(icon); src_data = c->data + c->lineSize * ( c-> h - 1 ); src_mask = c->mask + c->maskLine * ( c-> h - 1 ); dst = i->pixels; for ( y = 0; y < c-> h; y++) { Byte * s_data = src_data, * s_mask = src_mask; for ( x = 0; x < c-> w; x++) { *(dst++) = s_data[0]| (s_data[1] << 8)| (s_data[2] << 16)| (*(s_mask++) << 24) ; s_data += 3; } src_mask -= c->maskLine; src_data -= c->lineSize; } if ( kill ) Object_destroy(icon); XX-> user_pointer = XcursorImageLoadCursor(DISP, i); if ( XX-> user_pointer == None) { XcursorImageDestroy(i); warn( "error creating cursor"); return false; } XX-> user_xcursor = i; return true; #else DEFXX; Handle cursor; Bool noSZ = PIcon(icon)-> w != guts.cursor_width || PIcon(icon)-> h != guts.cursor_height; Bool noBPP = (PIcon(icon)-> type & imBPP) != 1; XColor xcb, xcw; PIcon c; if ( noSZ || noBPP) { cursor = CIcon(icon)->dup(icon); c = PIcon(cursor); if ( cursor == nilHandle) { warn( "Error duping user cursor"); return false; } if ( noSZ) { CIcon(cursor)-> stretch( cursor, guts.cursor_width, guts.cursor_height); if ( c-> w != guts.cursor_width || c-> h != guts.cursor_height) { warn( "Error stretching user cursor"); Object_destroy( cursor); return false; } } if ( noBPP) { CIcon(cursor)-> set_type( cursor, imMono); if ((c-> type & imBPP) != 1) { warn( "Error black-n-whiting user cursor"); Object_destroy( cursor); return false; } } } else cursor = icon; if ( !prima_create_icon_pixmaps( cursor, &XX-> user_p_source, &XX-> user_p_mask)) { warn( "Error creating user cursor pixmaps"); if ( noSZ || noBPP) Object_destroy( cursor); return false; } if ( noSZ || noBPP) Object_destroy( cursor); if ( hot_spot. x < 0) hot_spot. x = 0; if ( hot_spot. y < 0) hot_spot. y = 0; if ( hot_spot. x >= guts. cursor_width) hot_spot. x = guts. cursor_width - 1; if ( hot_spot. y >= guts. cursor_height) hot_spot. y = guts. cursor_height - 1; XX-> pointer_hot_spot = hot_spot; xcb. red = xcb. green = xcb. blue = 0; xcw. red = xcw. green = xcw. blue = 0xFFFF; xcb. pixel = guts. monochromeMap[0]; xcw. pixel = guts. monochromeMap[1]; xcb. flags = xcw. flags = DoRed | DoGreen | DoBlue; XX-> user_pointer = XCreatePixmapCursor( DISP, XX-> user_p_source, XX-> user_p_mask, &xcw, &xcb, hot_spot. x, guts.cursor_height - hot_spot. y - 1); if ( XX-> user_pointer == None) { warn( "error creating cursor from pixmaps"); return false; } return true; #endif }
void PreviewCursor::load(const QString &name, const QString &theme) { Display *dpy = QPaintDevice::x11AppDisplay(); if(m_pict) XRenderFreePicture(dpy, m_pict); if(m_handle) XFreeCursor(dpy, m_handle); m_pict = 0; m_handle = 0; m_width = m_height = 0; // Load the preview cursor image XcursorImage *image = XcursorLibraryLoadImage(name.latin1(), theme.latin1(), previewSize); // If the theme doesn't have this cursor, load the default cursor for now if(!image) image = XcursorLibraryLoadImage("left_ptr", theme.latin1(), previewSize); // TODO The old classic X cursors if(!image) return; // Auto-crop the image (some cursor themes use a fixed image size // for all cursors, and doing this results in correctly centered images) cropCursorImage(image); m_pict = createPicture(image); m_width = image->width; m_height = image->height; // Scale the image if its height is greater than 2x the requested size if(m_height > previewSize * 2.0) { double factor = double(previewSize * 2.0 / m_height); XTransform xform = {{{XDoubleToFixed(1.0), XDoubleToFixed(0), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(1.0), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(factor)}}}; XRenderSetPictureTransform(dpy, m_pict, &xform); m_width = int(m_width * factor); m_height = int(m_height * factor); } // We don't need this image anymore XcursorImageDestroy(image); // Load the actual cursor we will use int size = XcursorGetDefaultSize(dpy); XcursorImages *images = XcursorLibraryLoadImages(name.latin1(), theme.latin1(), size); if(images) { m_handle = XcursorImagesLoadCursor(dpy, images); XcursorImagesDestroy(images); } else { images = XcursorLibraryLoadImages("left_ptr", theme.latin1(), size); m_handle = XcursorImagesLoadCursor(dpy, images); XcursorImagesDestroy(images); } }
static GdkPixbuf * mouse_settings_themes_pixbuf_from_filename (const gchar *filename, guint size) { XcursorImage *image; GdkPixbuf *scaled, *pixbuf = NULL; gsize bsize; guchar *buffer, *p, tmp; gdouble wratio, hratio; gint dest_width, dest_height; /* load the image */ image = XcursorFilenameLoadImage (filename, size); if (G_LIKELY (image)) { /* buffer size */ bsize = image->width * image->height * 4; /* allocate buffer */ buffer = g_malloc (bsize); /* copy pixel data to buffer */ memcpy (buffer, image->pixels, bsize); /* swap bits */ for (p = buffer; p < buffer + bsize; p += 4) { tmp = p[0]; p[0] = p[2]; p[2] = tmp; } /* create pixbuf */ pixbuf = gdk_pixbuf_new_from_data (buffer, GDK_COLORSPACE_RGB, TRUE, 8, image->width, image->height, 4 * image->width, (GdkPixbufDestroyNotify) g_free, NULL); /* don't leak when creating the pixbuf failed */ if (G_UNLIKELY (pixbuf == NULL)) g_free (buffer); /* scale pixbuf if needed */ if (pixbuf && (image->height > size || image->width > size)) { /* calculate the ratio */ wratio = (gdouble) image->width / (gdouble) size; hratio = (gdouble) image->height / (gdouble) size; /* init */ dest_width = dest_height = size; /* set dest size */ /*if (hratio > wratio) dest_width = rint (image->width / hratio); else dest_height = rint (image->height / wratio);*/ dest_height = 16; dest_width = 16; /* scale pixbuf */ scaled = gdk_pixbuf_scale_simple (pixbuf, MAX (dest_width, 1), MAX (dest_height, 1), GDK_INTERP_BILINEAR); /* release and set scaled pixbuf */ g_object_unref (G_OBJECT (pixbuf)); pixbuf = scaled; } /* cleanup */ XcursorImageDestroy (image); } return pixbuf; }