Fixing GDK Cursor Creation Errors with Pixmap Data in RGtk2

gdkCursorNewFromPixmap Example Error

The gdkCursorNewFromPixmap function in RGtk2 can be finicky when it comes to creating cursors from pixmap data. In this post, we’ll explore the error caused by using the wrong type of pixmap and how to fix it.

Introduction to Gdk Pixmap

Before we dive into the error, let’s first understand what a GdkPixmap is. A GdkPixmap is a graphical representation of an image in GTK+, which is a library for creating graphical user interfaces. It allows developers to create windows, buttons, labels, and other UI elements.

In RGtk2, gdkPixmapNew is used to create a new GdkPixmap object from scratch or by loading an existing pixmap file. However, there’s another type of pixmap called GdkBitmap, which represents a bitmap image.

Creating Pixmap Data

Let’s take a look at the code snippet provided in the question:

library(RGtk2)

# This data is in X bitmap format, and can be created with the 'bitmap' utility in X11
cursor1_width <- 16
cursor1_height <- 16
cursor1_bits <- c(
  0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0x20,
  0x82, 0x41, 0x41, 0x82, 0x41, 0x82, 0x82, 0x41, 0x04, 0x20, 0x08, 0x10,
  0x10, 0x08, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01
)

cursor1mask_bits <- c(
  0x80, 0x01, 0xc0, 0x03, 0x60, 0x06, 0x30, 0x0c, 0x18, 0x18, 0x8c, 0x31,
  0xc6, 0x63, 0x63, 0xc6, 0x63, 0xc6, 0xc6, 0x63, 0x8c, 0x31, 0x18, 0x18,
  0x30, 0x0c, 0x60, 0x06, 0xc0, 0x03, 0x80, 0x01
)

fg <- c(65535, 0, 0) # Red.
bg <- c(0, 0, 65535) # Blue.

source <- gdkPixmapNew(NULL, cursor1_width, cursor1_height, 8)
mask <- gdkPixmapNew(NULL, cursor1_width, cursor1_height, 8)

cursor <- gdkCursorNewFromPixmap(source, mask, fg, bg, 0, 0)

The code above creates a new GdkPixmap object for the source and mask images using gdkPixmapNew. However, as we’ll see later, this is not the correct way to create a pixmap.

The Error: GdkBitmap vs. GdkPixmap

The error message provided in the question is:

Error in checkPtrType(source, "GdkPixmap") :
  object of class GdkBitmap, RGtkObject isn't a GdkPixmap
Calls: gdkCursorNewFromPixmap -> checkPtrType

The error occurs because gdkCursorNewFromPixmap expects a GdkPixmap object as its second argument, but instead receives a GdkBitmap object.

This is because the code uses gtk_pixmap_new (not gdkPixmapNew) to create the pixmap data, which returns a GdkBitmap object. To fix this, we need to use the correct type of pixmap for gdkCursorNewFromPixmap.

Using GtkPixmapNew Instead of GdkBitmapCreateFromData

The solution is to use gtk_pixmap_new (not gdkPixmapNew) instead of gtk_bitmap_create_from_data, which is deprecated. The corrected code snippet would look like this:

library(RGtk2)

# This data is in X bitmap format, and can be created with the 'bitmap' utility in X11
cursor1_width <- 16
cursor1_height <- 16

cursor1_bits <- c(
  0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0x20,
  0x82, 0x41, 0x41, 0x82, 0x41, 0x82, 0x82, 0x41, 0x04, 0x20, 0x08, 0x10,
  0x10, 0x08, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01
)

cursor1mask_bits <- c(
  0x80, 0x01, 0xc0, 0x03, 0x60, 0x06, 0x30, 0x0c, 0x18, 0x18, 0x8c, 0x31,
  0xc6, 0x63, 0x63, 0xc6, 0x63, 0xc6, 0xc6, 0x63, 0x8c, 0x31, 0x18, 0x18,
  0x30, 0x0c, 0x60, 0x06, 0xc0, 0x03, 0x80, 0x01
)

fg <- c(65535, 0, 0) # Red.
bg <- c(0, 0, 65535) # Blue.

source <- gtk_pixmap_new(cursor1_bits, cursor1_width, cursor1_height)
mask <- gtk_pixmap_new(cursor1mask_bits, cursor1_width, cursor1_height)

cursor <- gdkCursorNewFromPixmap(source, mask, fg, bg, 0, 0)

In this corrected version, gtk_pixmap_new is used to create the pixmap data, and gdkCursorNewFromPixmap receives the correct type of pixmap object as its second argument.

Conclusion

Creating cursors from pixmap data can be tricky in RGtk2. The key to resolving errors like the one mentioned above lies in using the correct type of pixmap for gdkCursorNewFromPixmap. By using gtk_pixmap_new instead of gdkPixmapNew, we can ensure that our code produces a valid GdkPixmap object and avoid errors like the one described.


Last modified on 2025-04-23