Skip to content

Commit

Permalink
Merge branch 'mouse-funcs' of https://github.com/Kylogias/rawdraw int…
Browse files Browse the repository at this point in the history
…o Kylogias-mouse-funcs
  • Loading branch information
cnlohr committed Oct 3, 2024
2 parents 565787e + d320305 commit 776c2ca
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 3 deletions.
15 changes: 15 additions & 0 deletions CNFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,20 @@ void CNFGChangeWindowTitle( const char * windowtitle );
void CNFGSetWindowIconData( int w, int h, uint32_t * data );
int CNFGSetupWMClass( const char * WindowName, int w, int h , char * wm_res_name_ , char * wm_res_class_ );

// Mouse related functions on systems that support it.

// enum just in case we want more cursor shapes
typedef enum {
CNFG_CURSOR_HIDDEN, CNFG_CURSOR_ARROW, CNFG_CURSOR_LAST
} CNFGCursorShape;

// This may put a motion event into the queue, which will call HandleMotion
void CNFGSetMousePosition( int x, int y );

void CNFGConfineMouse( int confined );
void CNFGSetCursor( CNFGCursorShape shape );


//If you're using a batching renderer, for instance on Android or an OpenGL
//You will need to call this function inbetewen swtiching properties of drawing. This is usually
//only needed if you calling OpenGL / OGLES functions directly and outside of CNFG.
Expand Down Expand Up @@ -190,6 +204,7 @@ extern float CNFGVertDataV[CNFG_BATCH*3];
extern uint32_t CNFGVertDataC[CNFG_BATCH];
#endif

#define CNFG_KEY_FOCUS 0xf000

#if defined(WINDOWS) || defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)

Expand Down
48 changes: 48 additions & 0 deletions CNFGWinDriver.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,49 @@ void CNFGSwapBuffers()
}
#endif

CNFGCursorShape CNFGCurShape = CNFG_CURSOR_ARROW;

void CNFGSetMousePosition( int x, int y ) {
RECT window;

int bordersize = GetSystemMetrics( SM_CXSIZEFRAME );

GetWindowRect( CNFGlsHWND, &window );
x += window.left + bordersize;
y += window.top + GetSystemMetrics( SM_CYCAPTION ) + bordersize;

SetCursorPos( x, y );
}

void CNFGConfineMouse( int confined ) {
if ( !confined ) {
ClipCursor( NULL );
return;
}

int bordersize = GetSystemMetrics( SM_CXSIZEFRAME );
RECT window;
GetWindowRect( CNFGlsHWND, &window );
window.left += bordersize;
window.top += GetSystemMetrics( SM_CYCAPTION ) + bordersize;
window.right -= bordersize;
window.bottom -= bordersize;

ClipCursor( &window );
}

void CNFGSetCursor( CNFGCursorShape shape ) {
if (shape == CNFGCurShape ) return;

// If the current shape's visibility is the opposite of the new shape, toggle the cursor visibility
// According to MSDN, ShowCursor increments and decrements an internal counter, which is used to determine visibility
// The internal counter seemingly has no limit
if ( shape == CNFG_CURSOR_HIDDEN && CNFGCurShape != CNFG_CURSOR_HIDDEN ) ShowCursor( FALSE );
else if ( shape != CNFG_CURSOR_HIDDEN && CNFGCurShape == CNFG_CURSOR_HIDDEN ) ShowCursor( TRUE );

CNFGCurShape = shape;
}

void CNFGGetDimensions( short * x, short * y )
{
static short lastx, lasty;
Expand Down Expand Up @@ -135,6 +178,11 @@ LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
break;
#endif
case WM_KILLFOCUS:
case WM_SETFOCUS:
CNFGLastScancode = 0;
HandleKey( CNFG_KEY_FOCUS, msg == WM_SETFOCUS );
return 0;
case WM_CLOSE:
if( HandleDestroy() )
return 0;
Expand Down
33 changes: 32 additions & 1 deletion CNFGXDriver.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>

#include <stdio.h>
Expand Down Expand Up @@ -155,6 +156,25 @@ void CNFGClearTransparencyLevel()
}
#endif

void CNFGSetMousePosition( int x, int y ) {
XWarpPointer( CNFGDisplay, None, CNFGWindow, 0, 0, 0, 0, x, y );
}

void CNFGConfineMouse( int confined ) {
if (confined) {
XGrabPointer( CNFGDisplay, CNFGWindow, True, 0, GrabModeAsync, GrabModeAsync, CNFGWindow, None, CurrentTime );
} else {
XUngrabPointer( CNFGDisplay, CurrentTime );
}
}

Cursor CNFGCursors[CNFG_CURSOR_LAST] = { None };

void CNFGSetCursor( CNFGCursorShape shape ) {
if (shape == CNFG_CURSOR_ARROW) XUndefineCursor( CNFGDisplay, CNFGWindow );
else XDefineCursor( CNFGDisplay, CNFGWindow, CNFGCursors[shape] );
}

int FullScreen = 0;

void CNFGGetDimensions( short * x, short * y )
Expand Down Expand Up @@ -202,7 +222,7 @@ static void InternalLinkScreenAndGo( const char * WindowName )
fprintf( stderr, "Pre-existing XClassHint\n" );
}

XSelectInput (CNFGDisplay, CNFGWindow, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask );
XSelectInput (CNFGDisplay, CNFGWindow, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask | FocusChangeMask );


CNFGWindowGC = XCreateGC(CNFGDisplay, CNFGWindow, 0, 0);
Expand Down Expand Up @@ -391,6 +411,12 @@ int CNFGSetup( const char * WindowName, int w, int h )
CFNGWMDeleteWindow = XInternAtom( CNFGDisplay, "WM_DELETE_WINDOW", False );
XSetWMProtocols( CNFGDisplay, CNFGWindow, &CFNGWMDeleteWindow, 1 );

// X11 doesn't have a concept of a hidden cursor. Make a blank cursor as a substitute
XColor col = { 0 };
Pixmap blank = XCreateBitmapFromData( CNFGDisplay, CNFGWindow, (char*)(&col), 1, 1 );
CNFGCursors[CNFG_CURSOR_HIDDEN] = XCreatePixmapCursor( CNFGDisplay, blank, blank, &col, &col, 0, 0 );
XFreePixmap( CNFGDisplay, blank );

#ifdef CNFGOGL
glXMakeCurrent( CNFGDisplay, CNFGWindow, CNFGCtx );
#endif
Expand Down Expand Up @@ -473,6 +499,11 @@ int CNFGHandleInput()
case MotionNotify:
HandleMotion( report.xmotion.x, report.xmotion.y, ButtonsDown>>1 );
break;
case FocusIn:
case FocusOut:
CNFGLastScancode = 0;
HandleKey( CNFG_KEY_FOCUS, report.type == FocusIn );
break;
case ClientMessage:
if ( report.xclient.data.l[0] == CFNGWMDeleteWindow )
return 0;
Expand Down
98 changes: 96 additions & 2 deletions rawdraw_sf.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//This file was automatically generated by Makefile at https://github.com/cntools/rawdraw
//Generated from files git hash f7f8fcb9537c65f2097cf1bfd87a7979d21e7c1c on Thu Oct 3 04:32:19 PM PDT 2024 (This is not the git hash of this file)
//Generated from files git hash 565787ec7c65e4f8289ce4b2e7fc5ba20ab3833a on Thu Oct 3 04:35:48 PM PDT 2024 (This is not the git hash of this file)
// Copyright 2010-2021 <>< CNLohr, et. al. (Several other authors, many but not all mentioned)
// Licensed under the MIT/x11 or NewBSD License you choose.
//
Expand Down Expand Up @@ -164,6 +164,20 @@ void CNFGChangeWindowTitle( const char * windowtitle );
void CNFGSetWindowIconData( int w, int h, uint32_t * data );
int CNFGSetupWMClass( const char * WindowName, int w, int h , char * wm_res_name_ , char * wm_res_class_ );

// Mouse related functions on systems that support it.

// enum just in case we want more cursor shapes
typedef enum {
CNFG_CURSOR_HIDDEN, CNFG_CURSOR_ARROW, CNFG_CURSOR_LAST
} CNFGCursorShape;

// This may put a motion event into the queue, which will call HandleMotion
void CNFGSetMousePosition( int x, int y );

void CNFGConfineMouse( int confined );
void CNFGSetCursor( CNFGCursorShape shape );


//If you're using a batching renderer, for instance on Android or an OpenGL
//You will need to call this function inbetewen swtiching properties of drawing. This is usually
//only needed if you calling OpenGL / OGLES functions directly and outside of CNFG.
Expand Down Expand Up @@ -192,6 +206,7 @@ extern float CNFGVertDataV[CNFG_BATCH*3];
extern uint32_t CNFGVertDataC[CNFG_BATCH];
#endif

#define CNFG_KEY_FOCUS 0xf000

#if defined(WINDOWS) || defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)

Expand Down Expand Up @@ -3764,6 +3779,49 @@ void CNFGSwapBuffers()
}
#endif

CNFGCursorShape CNFGCurShape = CNFG_CURSOR_ARROW;

void CNFGSetMousePosition( int x, int y ) {
RECT window;

int bordersize = GetSystemMetrics( SM_CXSIZEFRAME );

GetWindowRect( CNFGlsHWND, &window );
x += window.left + bordersize;
y += window.top + GetSystemMetrics( SM_CYCAPTION ) + bordersize;

SetCursorPos( x, y );
}

void CNFGConfineMouse( int confined ) {
if ( !confined ) {
ClipCursor( NULL );
return;
}

int bordersize = GetSystemMetrics( SM_CXSIZEFRAME );
RECT window;
GetWindowRect( CNFGlsHWND, &window );
window.left += bordersize;
window.top += GetSystemMetrics( SM_CYCAPTION ) + bordersize;
window.right -= bordersize;
window.bottom -= bordersize;

ClipCursor( &window );
}

void CNFGSetCursor( CNFGCursorShape shape ) {
if (shape == CNFGCurShape ) return;

// If the current shape's visibility is the opposite of the new shape, toggle the cursor visibility
// According to MSDN, ShowCursor increments and decrements an internal counter, which is used to determine visibility
// The internal counter seemingly has no limit
if ( shape == CNFG_CURSOR_HIDDEN && CNFGCurShape != CNFG_CURSOR_HIDDEN ) ShowCursor( FALSE );
else if ( shape != CNFG_CURSOR_HIDDEN && CNFGCurShape == CNFG_CURSOR_HIDDEN ) ShowCursor( TRUE );

CNFGCurShape = shape;
}

void CNFGGetDimensions( short * x, short * y )
{
static short lastx, lasty;
Expand Down Expand Up @@ -3834,6 +3892,11 @@ LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
break;
#endif
case WM_KILLFOCUS:
case WM_SETFOCUS:
CNFGLastScancode = 0;
HandleKey( CNFG_KEY_FOCUS, msg == WM_SETFOCUS );
return 0;
case WM_CLOSE:
if( HandleDestroy() )
return 0;
Expand Down Expand Up @@ -5570,6 +5633,7 @@ void AndroidSendToBack( int param )
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>

#include <stdio.h>
Expand Down Expand Up @@ -5710,6 +5774,25 @@ void CNFGClearTransparencyLevel()
}
#endif

void CNFGSetMousePosition( int x, int y ) {
XWarpPointer( CNFGDisplay, None, CNFGWindow, 0, 0, 0, 0, x, y );
}

void CNFGConfineMouse( int confined ) {
if (confined) {
XGrabPointer( CNFGDisplay, CNFGWindow, True, 0, GrabModeAsync, GrabModeAsync, CNFGWindow, None, CurrentTime );
} else {
XUngrabPointer( CNFGDisplay, CurrentTime );
}
}

Cursor CNFGCursors[CNFG_CURSOR_LAST] = { None };

void CNFGSetCursor( CNFGCursorShape shape ) {
if (shape == CNFG_CURSOR_ARROW) XUndefineCursor( CNFGDisplay, CNFGWindow );
else XDefineCursor( CNFGDisplay, CNFGWindow, CNFGCursors[shape] );
}

int FullScreen = 0;

void CNFGGetDimensions( short * x, short * y )
Expand Down Expand Up @@ -5757,7 +5840,7 @@ static void InternalLinkScreenAndGo( const char * WindowName )
fprintf( stderr, "Pre-existing XClassHint\n" );
}

XSelectInput (CNFGDisplay, CNFGWindow, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask );
XSelectInput (CNFGDisplay, CNFGWindow, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask | FocusChangeMask );


CNFGWindowGC = XCreateGC(CNFGDisplay, CNFGWindow, 0, 0);
Expand Down Expand Up @@ -5946,6 +6029,12 @@ int CNFGSetup( const char * WindowName, int w, int h )
CFNGWMDeleteWindow = XInternAtom( CNFGDisplay, "WM_DELETE_WINDOW", False );
XSetWMProtocols( CNFGDisplay, CNFGWindow, &CFNGWMDeleteWindow, 1 );

// X11 doesn't have a concept of a hidden cursor. Make a blank cursor as a substitute
XColor col = { 0 };
Pixmap blank = XCreateBitmapFromData( CNFGDisplay, CNFGWindow, (char*)(&col), 1, 1 );
CNFGCursors[CNFG_CURSOR_HIDDEN] = XCreatePixmapCursor( CNFGDisplay, blank, blank, &col, &col, 0, 0 );
XFreePixmap( CNFGDisplay, blank );

#ifdef CNFGOGL
glXMakeCurrent( CNFGDisplay, CNFGWindow, CNFGCtx );
#endif
Expand Down Expand Up @@ -6028,6 +6117,11 @@ int CNFGHandleInput()
case MotionNotify:
HandleMotion( report.xmotion.x, report.xmotion.y, ButtonsDown>>1 );
break;
case FocusIn:
case FocusOut:
CNFGLastScancode = 0;
HandleKey( CNFG_KEY_FOCUS, report.type == FocusIn );
break;
case ClientMessage:
if ( report.xclient.data.l[0] == CFNGWMDeleteWindow )
return 0;
Expand Down

0 comments on commit 776c2ca

Please sign in to comment.