Pointer sessions

Updated: April 19, 2023

Pointer input sessions are created with the type SCREEN_EVENT_POINTER and are typically used to control the shape and position of the cursor.

The SCREEN_PROPERTY_MODE property for pointer sessions isn't used. However, the following session properties are applicable to pointer sessions:

SCREEN_PROPERTY_ACCELERATION
A set of six integers that represent the linear coefficients for x and y, the quadratic coefficients for x and y, and the minimum and maximum velocity.
SCREEN_PROPERTY_ALTERNATE
Specifies an alternate session. You can make a session an alternate for another (usually, both sessions are input regions). Normally, sessions that are alternates are also windowless. You can set up your application such that if your pointer is in one region, it jumps to another session. For example, if your pointer is over a specific area, you can move to a different display. As a window manager, you can make a session an alternate for another session. You can also tag a session as an alternate. The alternate comes into play in the geometry for multiple displays using a pointer.
SCREEN_PROPERTY_BRUSH
A pointer to the pixmap containing the brush to be used. All move events (e.g., a click then drag) will translate to drawing on your front buffer.
SCREEN_PROPERTY_CURSOR
Specifies a cursor shape to display when the pointer is within the region of the session. The cursor can be one of the shapes defined in Screen cursor shapes. Typically you'd use this property on an input region so that you can change the shape of the cursor when the pointer is over a specific area.
SCREEN_PROPERTY_SPEED
The speed for the horizontal and vertical directions for the pointer device (similar to mouse sensitivity). The speed is given as the ratio between the number of pixels the cursor moves on the display and how far the device is physically moved.

Other session properties applicable to pointer sessions are SCREEN_PROPERTY_BRUSH_CLIP_POSITION and SCREEN_PROPERTY_BRUSH_CLIP_SIZE, but it's not usually necessary to use these properties because when you use sessions, you can define the size and position via the session's input region. They are made available more so for windows.

Cursor across multiple displays

When you have multiple displays, the effect of your cursor moving from one display to another is achieved by using the SCREEN_PROPERTY_ALTERNATE property of pointer sessions.

You can make your pointer jump from one session to another by creating appropriate pointer sessions that are associated to each display and then setting each of the sessions' SCREEN_PROPERTY_ALTERNATE property to the appropriate session. When the pointer jumps to a different session, the cursor becomes visible on a different display.

Let's say that you have two displays and you want to show your cursor on the first display. As the pointer device moves towards the right, you want the cursor to move and eventually be shown on the second display.



Figure 1. Moving your cursor across two displays

In this example, your application uses two displays and two pointer sessions.



Figure 2. Displays and pointer sessions

Create pointer sessions at the boundaries of your displays where you want the cursor to stop and start being visble. The size of your pointer sessions doesn't need to be more than one pixel in width for the purpose of these sessions. The wider the sessions, the more space you'll see between where the cursor disappears from one display and reappears on the second. In this example, the cursor is travelling from left to right, from Display 1 (dpy1) to Display 2 (dpy2). Therefore, you need to create two sessions. Session 1 (ssn1) is positioned at the right-most edge of Display 1 because that is the point where the cursor will stop being visible on Display 1. Session 2 (ssn2) is positioned at the left-most edge of Display 2 because that is the point where the cursor will start being visible on Display 2. For example:

...
int w1 = 1280; /* width of Display 1 */
int h1 = 720; /* height of Display 1 */
int w2 = 1280; /* width of Display 2 */
int h2 = 720; /* height of Display 2 */
int zorder = 1000; /* Make the sessions top-most. */
...
screen_display_t dpy1; /* handle to Display 1 */
screen_display_t dpy2; /* handle to Display 2 */
...
screen_session_t ssn1;
screen_session_t ssn2;
int ssn1_pos[2] = { (w1-1), 0 };
int ssn1_size[2] = { 1, h1 };
int ssn2_pos[2] = { 0, 0 };
int ssn2_size[2] = { 1, h2 };
...
screen_create_session_type(&ssn1, context, SCREEN_EVENT_POINTER);
screen_set_session_property_pv(ssn1, SCREEN_PROPERTY_DISPLAY, (void**) &dpy1);
screen_set_session_property_iv(ssn1, SCREEN_PROPERTY_POSITION, ssn1_pos);
screen_set_session_property_iv(ssn1, SCREEN_PROPERTY_SIZE, ssn1_size);
screen_set_session_property_iv(ssn1, SCREEN_PROPERTY_ZORDER, &zorder);

screen_create_session_type(&ssn2, context, SCREEN_EVENT_POINTER);
screen_set_session_property_pv(ssn2, SCREEN_PROPERTY_DISPLAY, (void**) &dpy2);
screen_set_session_property_iv(ssn2, SCREEN_PROPERTY_POSITION, ssn2_pos);
screen_set_session_property_iv(ssn2, SCREEN_PROPERTY_SIZE, ssn2_size);
screen_set_session_property_iv(ssn2, SCREEN_PROPERTY_ZORDER, &zorder);
... 
            
Note: You must set the z-order of these sessions so that they are the situated at the top-most relative to other sessions.

After you create your sessions, you must set the SCREEN_PROPERTY_ALTERNATE property of either one of the sessions so that they are associated with each other. The SCREEN_PROPERTY_ALTERNATE property indicates which session next receives input. In this example, you need to indicate that ssn2 is the alternate for ssn1 because the position of ssn2 is where you want the cursor to be visible once it leaves ssn1. For example:

...
screen_set_session_property_pv(ssn1, SCREEN_PROPERTY_ALTERNATE, (void**) &ssn2);
...
            

It's not necessary to set the SCREEN_PROPERTY_ALTERNATE property of the other session because Screen automatically makes the reciprocal association when you set the SCREEN_PROPERTY_ALTERNATE property.

If the size of the sessions for each display is different, Screen scales accordingly to determine the position of the cursor where it appears in the new session.

Note: You must have the appropriate configurations for your pointer device and cursor visibility in order to see your cursor on the displays. See sections Configure globals subsection and Configure display subsection for more information.

Cursor shape

You can change your cursor shape for a window, or even a specific area within a window by using a pointer input session. If you're managing cursor shapes, you'll need to have specified the image associated with the shapes you want to use through the Screen configuration file, graphics.conf.

Valid shapes for your cursor are defined by the type Screen cursor shapes.

Refer to the cursor-type parameter of Configure display subsection for more details.

Once you've configured the cursor shapes, your application can specify a cursor shape for a window:

...
screen_session_t session;
int cursor_shape = SCREEN_CURSOR_SHAPE_ARROW;
screen_create_session_type(&session, context, SCREEN_EVENT_POINTER);
screen_set_session_property_pv(session, SCREEN_PROPERTY_WINDOW, (void**) &window);
screen_set_session_property_iv(session, SCREEN_PROPERTY_CURSOR, cursor_shape);
...
           

or for a specific area:

...
screen_session_t session;
int cursor_shape = SCREEN_CURSOR_SHAPE_HAND;
screen_create_session_type(&session, context, SCREEN_EVENT_POINTER);
screen_set_session_property_pv(session, SCREEN_PROPERTY_WINDOW, (void**) &window);
screen_set_session_property_iv(session, SCREEN_PROPERTY_POSITION, pos);
screen_set_session_property_iv(session, SCREEN_PROPERTY_SIZE, size);
screen_set_session_property_iv(session, SCREEN_PROPERTY_CURSOR, cursor_shape);
...
           

Gaming mode

In gaming mode, you might want to hide the cursor. In this case, you can set the cursor shape to SCREEN_CURSOR_SHAPE_NONE:

...
screen_session_t session;
int cursor_shape = SCREEN_CURSOR_SHAPE_NONE;
screen_create_session_type(&session, context, SCREEN_EVENT_POINTER);
screen_set_session_property_pv(session, SCREEN_PROPERTY_WINDOW, (void**) &window);
screen_set_session_property_iv(session, SCREEN_PROPERTY_CURSOR, cursor_shape);
...
           
In the case of gaming, you might find it more useful to use displacement instead of the position of the cursor.