<commit_before>/*
 * Copyright (C) 2003 <NAME>
 * Copyright (C) 1995 <NAME>
 * Copyright (C) 1993 <NAME>
 * Copyright (C) 1993 <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#define LOCAL_DEBUG
#define EVENT_TRACE

#include "../../configure.h"

#include "asinternals.h"

#include <limits.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>

#include "../../libAfterStep/wmprops.h"
#include "../../libAfterStep/moveresize.h"

#include <X11/keysym.h>

/***********************************************************************
 *  _______________________EVENT HANDLING ______________________________
 *
 *  HandleEvents  - event loop
 *  DigestEvent   - preprocesses event - finds ASWindow, context etc.
 *  DispatchEvent - calls appropriate handler for the event
 ************************************************************************/
void DigestEvent    ( ASEvent *event );
void afterstep_wait_pipes_input ();
void SetTimer (int delay);

void
HandleEvents ()
{
    /* this is the only loop that allowed to run ExecutePendingFunctions(); */
    ASEvent event;
    Bool has_x_events = False ;
    while (True)
    {
        while((has_x_events = XPending (dpy)))
        {
            if( ASNextEvent (&(event.x), True) )
            {
                DigestEvent( &event );
                DispatchEvent( &event, False );
            }

            ExecutePendingFunctions();
        }
        afterstep_wait_pipes_input ();
        ExecutePendingFunctions();
    }
}

/***************************************************************************
 * Wait for all mouse buttons to be released
 * This can ease some confusion on the part of the user sometimes
 *
 * Discard superflous button events during this wait period.
 ***************************************************************************/
void
InteractiveMoveLoop ()
{
    ASEvent event;
    Bool has_x_events = False ;
    while (Scr.moveresize_in_progress != NULL )
    {
        while((has_x_events = XPending (dpy)))
        {
            if( ASNextEvent (&(event.x), True) )
            {
                DigestEvent( &event );
                DispatchEvent( &event, False );
            }
            if( Scr.moveresize_in_progress == NULL )
                return;
        }
        afterstep_wait_pipes_input ();
    }
}



void
WaitForButtonsUpLoop ()
{
	XEvent        JunkEvent;
    unsigned int  mask;

    if( !get_flags( AfterStepState, ASS_PointerOutOfScreen) )
	{
		do
		{
			XAllowEvents (dpy, ReplayPointer, CurrentTime);
            ASQueryPointerMask(&mask);
        	ASFlushAndSync();
		}while( (mask & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask)) != 0 );

    	while (ASCheckMaskEvent ( ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, &JunkEvent))
			XAllowEvents (dpy, ReplayPointer, CurrentTime);
	}
}

Bool
WaitEventLoop( ASEvent *event, int finish_event_type, long timeout )
{
	unsigned long mask = ButtonPressMask | ButtonReleaseMask |
						 ExposureMask | KeyPressMask | ButtonMotionMask |
						 PointerMotionMask	/* | EnterWindowMask | LeaveWindowMask */;
	Bool done = False ;

    while (!done)
	{
		/* block until there is an event */
        ASFlushIfEmpty();
        ASMaskEvent ( mask, &(event->x));

        if( event->x.type == KeyPress )
            KeyboardShortcuts (&(event->x), finish_event_type, 20);
            /* above line might have changed event code !!!*/
        else if (event->x.type == ButtonPress )
			XAllowEvents (dpy, ReplayPointer, CurrentTime);

        if( event->x.type == finish_event_type )
		{
			done = True ;
			if( event->x.xbutton.window == Scr.Root ) 
				event->x.xbutton.window = event->x.xbutton.subwindow ;
			/* otherwise event will be reported as if it occured relative to 
			   root window */
		}
        DigestEvent( event );
        DispatchEvent( event, done );
    }

    return True ;
}

/*****************************************************************************
 * Waits click_time, or until it is evident that the user is not
 * clicking, but is moving the cursor
 ****************************************************************************/
Bool
IsClickLoop( ASEvent *event, unsigned int end_mask, unsigned int click_time )
{
	int dx = 0, dy = 0;
	int x_orig = event->x.xbutton.x_root ;
	int y_orig = event->x.xbutton.y_root ;
    /* we are in the middle of running Complex function - we must only do mandatory
     * processing on received events, but do not actually handle them !!
     * Client window affected, as well as the context must not change -
     * only the X event could */
    ASEvent tmp_event ;
    register XEvent *xevt = &(tmp_event.x) ;

    ASSync(False);
	start_ticker (click_time*10);
    do
	{
        sleep_a_little (100);
        if (ASCheckMaskEvent (end_mask, xevt))
        {
            DigestEvent( &tmp_event );
            event->x = *xevt ;                 /* everything else must remain the same !!! */
            return True;
        }
        if( is_tick() )
			break;

        LOCAL_DEBUG_OUT( "total=%d/click_time = %d", total, click_time );
        if (ASCheckMaskEvent ( ButtonMotionMask | PointerMotionMask, xevt))
		{
			dx = x_orig - xevt->xmotion.x_root;
			dy = y_orig - xevt->xmotion.y_root;
            DigestEvent( &tmp_event );
		    event->x = *xevt ;                 /* everything else must remain the same !!! */
		}
    }while( dx > -5 && dx < 5 && dy > -5 && dy < 5 );

	return False;
}

Bool
WaitWindowLoop( char *pattern, long timeout )
{
	wild_reg_exp *wrexp = compile_wild_reg_exp( pattern );
	Bool done = False ;
	ASEvent event ;
	Bool has_x_events ;

	if( wrexp == NULL )
		return False;

	start_ticker ((timeout<=0?DEFAULT_WINDOW_WAIT_TIMEOUT:timeout)*10);
<commit_msg>compile bug in event.c<commit_after>/*
 * Copyright (C) 2003 <NAME>
 * Copyright (C) 1995 <NAME>
 * Copyright (C) 1993 <NAME>
 * Copyright (C) 1993 <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#define LOCAL_DEBUG
#define EVENT_TRACE

#include "../../configure.h"

#include "asinternals.h"

#include <limits.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>

#include "../../libAfterStep/wmprops.h"
#include "../../libAfterStep/moveresize.h"

#include <X11/keysym.h>

/***********************************************************************
 *  _______________________EVENT HANDLING ______________________________
 *
 *  HandleEvents  - event loop
 *  DigestEvent   - preprocesses event - finds ASWindow, context etc.
 *  DispatchEvent - calls appropriate handler for the event
 ************************************************************************/
void DigestEvent    ( ASEvent *event );
void afterstep_wait_pipes_input ();
void SetTimer (int delay);

void
HandleEvents ()
{
    /* this is the only loop that allowed to run ExecutePendingFunctions(); */
    ASEvent event;
    Bool has_x_events = False ;
    while (True)
    {
        while((has_x_events = XPending (dpy)))
        {
            if( ASNextEvent (&(event.x), True) )
            {
                DigestEvent( &event );
                DispatchEvent( &event, False );
            }

            ExecutePendingFunctions();
        }
        afterstep_wait_pipes_input ();
        ExecutePendingFunctions();
    }
}

/***************************************************************************
 * Wait for all mouse buttons to be released
 * This can ease some confusion on the part of the user sometimes
 *
 * Discard superflous button events during this wait period.
 ***************************************************************************/
void
InteractiveMoveLoop ()
{
    ASEvent event;
    Bool has_x_events = False ;
    while (Scr.moveresize_in_progress != NULL )
    {
        while((has_x_events = XPending (dpy)))
        {
            if( ASNextEvent (&(event.x), True) )
            {
                DigestEvent( &event );
                DispatchEvent( &event, False );
            }
            if( Scr.moveresize_in_progress == NULL )
                return;
        }
        afterstep_wait_pipes_input ();
    }
}



void
WaitForButtonsUpLoop ()
{
	XEvent        JunkEvent;
    unsigned int  mask;

    if( !get_flags( AfterStepState, ASS_PointerOutOfScreen) )
	{
		do
		{
			XAllowEvents (dpy, ReplayPointer, CurrentTime);
            ASQueryPointerMask(&mask);
        	ASFlushAndSync();
		}while( (mask & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask)) != 0 );

    	while (ASCheckMaskEvent ( ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, &JunkEvent))
			XAllowEvents (dpy, ReplayPointer, CurrentTime);
	}
}

Bool
WaitEventLoop( ASEvent *event, int finish_event_type, long timeout )
{
	unsigned long mask = ButtonPressMask | ButtonReleaseMask |
						 ExposureMask | KeyPressMask | ButtonMotionMask |
						 PointerMotionMask	/* | EnterWindowMask | LeaveWindowMask */;
	Bool done = False ;

    while (!done)
	{
		/* block until there is an event */
        ASFlushIfEmpty();
        ASMaskEvent ( mask, &(event->x));

        if( event->x.type == KeyPress )
            KeyboardShortcuts (&(event->x), finish_event_type, 20);
            /* above line might have changed event code !!!*/
        else if (event->x.type == ButtonPress )
			XAllowEvents (dpy, ReplayPointer, CurrentTime);

        if( event->x.type == finish_event_type )
		{
			done = True ;
			if( event->x.xbutton.window == Scr.Root )
				event->x.xbutton.window = event->x.xbutton.subwindow ;
			/* otherwise event will be reported as if it occured relative to
			   root window */
		}
        DigestEvent( event );
        DispatchEvent( event, done );
    }

    return True ;
}

/*****************************************************************************
 * Waits click_time, or until it is evident that the user is not
 * clicking, but is moving the cursor
 ****************************************************************************/
Bool
IsClickLoop( ASEvent *event, unsigned int end_mask, unsigned int click_time )
{
	int dx = 0, dy = 0;
	int x_orig = event->x.xbutton.x_root ;
	int y_orig = event->x.xbutton.y_root ;
    /* we are in the middle of running Complex function - we must only do mandatory
     * processing on received events, but do not actually handle them !!
     * Client window affected, as well as the context must not change -
     * only the X event could */
    ASEvent tmp_event ;
    register XEvent *xevt = &(tmp_event.x) ;

    ASSync(False);
	start_ticker (click_time*10);
    do
	{
        sleep_a_little (100);
        if (ASCheckMaskEvent (end_mask, xevt))
        {
            DigestEvent( &tmp_event );
            event->x = *xevt ;                 /* everything else must remain the same !!! */
            return True;
        }
        if( is_tick() )
			break;

        if (ASCheckMaskEvent ( ButtonMotionMask | PointerMotionMask, xevt))
		{
			dx = x_orig - xevt->xmotion.x_root;
			dy = y_orig - xevt->xmotion.y_root;
            DigestEvent( &tmp_event );
		    event->x = *xevt ;                 /* everything else must remain the same !!! */
		}
    }while( dx > -5 && dx < 5 && dy > -5 && dy < 5 );

	return False;
}

Bool
WaitWindowLoop( char *pattern, long timeout )
{
	wild_reg_exp *wrexp = compile_wild_reg_exp( pattern );
	Bool done = False ;
	ASEvent event ;
	Bool has_x_events ;

	if( wrexp == NULL )
		return False;

	start_ticker ((timeout<=0?DEFAULT_WINDOW_WAIT_TIMEOUT:timeout)*10);

{'fraction_non_alphanumeric': 0.16678406511700714, 'fraction_numerical': 0.00767003208890976, 'mean_word_length': 2.8945443462359037, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2845863', 'n_tokens_mistral': 3895, 'n_tokens_neox': 3615, 'n_words': 1124}