⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coolnext.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* coolnext.c - CNextEvent function and support, and various event		handlers and utils   Copyright (C) 1996-2000 Paul Sheer   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., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. *//* #define DEBUG *//* #define DEBUG_ENTRY */#include <config.h>#include <stdio.h>#include <my_string.h>#include <stdlib.h>#include <stdarg.h>#include <X11/Intrinsic.h>#include "lkeysym.h"#include "stringtools.h"#include "app_glob.c"#include "coolwidget.h"#include "coollocal.h"#include "drawings.h"#include "edit.h"#include "editcmddef.h"#include "widget3d.h"#include "mad.h"int last_region = 0;int (*global_alarm_callback[33]) (CWidget *, XEvent *, CEvent *) = {    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};extern Pixmap Cswitchon, Cswitchoff;#ifdef HAVE_DNDextern Atom DndProtocol, OldDndProtocol;#endifvoid add_to_focus_stack (Window w);void selection_clear (void); /* from editwidget.c */int option_mouse_double_click = 300;int option_middle_button_pastes = 1;/* converts button presses from buttons 2 through 5 to button presses from 2 only, also gets double clicks */void resolve_button (XEvent * xevent, CEvent * cwevent){    static Time thyme_press = 0, thyme_release = 0;    static Window window = 0;    static int x, y;    cwevent->state = xevent->xbutton.state;    if (cwevent->state & (Button2Mask | Button3Mask /*| Button4Mask | Button5Mask */ ))	cwevent->state |= Button2Mask;    switch (xevent->type) {    case ButtonRepeat:    case ButtonRelease:    case ButtonPress:	cwevent->button = xevent->xbutton.button;	if (cwevent->button == Button4 || cwevent->button == Button5) {	    /* ahaack: wheel mouse mapped as button 4 and 5 */	    return;	}	if (cwevent->button == Button2 || cwevent->button == Button3	    || cwevent->button == Button4 || cwevent->button == Button5) {	    cwevent->button = Button2;	}	cwevent->x = xevent->xbutton.x;	cwevent->y = xevent->xbutton.y;	if (xevent->type != ButtonRepeat) {	    if (window == xevent->xany.window)		if (abs (x - cwevent->x) < 4 && abs (y - cwevent->y) < 4) {		    if (abs (xevent->xmotion.time - thyme_press) < option_mouse_double_click &&			xevent->type == ButtonPress)			thyme_press = cwevent->double_click = 1;		    if (abs (xevent->xmotion.time - thyme_release) < option_mouse_double_click &&			xevent->type == ButtonRelease)			thyme_release = cwevent->double_click = 1;		}	    if (xevent->type == ButtonPress)		thyme_press = xevent->xbutton.time;	    else		thyme_release = xevent->xbutton.time;	}	x = xevent->xbutton.x;	y = xevent->xbutton.y;	break;    case MotionNotify:	x = cwevent->x = xevent->xmotion.x;	y = cwevent->y = xevent->xmotion.y;	break;    }    window = xevent->xany.window;}static long lower_window_callback (CWidget * w){    if (w->position & WINDOW_ALWAYS_LOWERED)	XLowerWindow (CDisplay, w->winid);    return 0;}/*sends all windows that are marked top_bottom = 1 to the bottom */void CLowerWindows (void){    for_all_widgets ((void *) lower_window_callback, 0, 0);}static long raise_window_callback (CWidget * w){    if (w->position & WINDOW_ALWAYS_RAISED)	XRaiseWindow (CDisplay, w->winid);    return 0;}/*sends all windows that are marked top_bottom = 2 to the top */void CRaiseWindows (void){    for_all_widgets ((void *) raise_window_callback, 0, 0);}/* {{{ here is an internal event queue handler to send events without going through XLib *//*   We want to be able to send our own events internally   because XSendEvent sometimes doesn't force the an   event to be processed and the event sits on the queue   with its thumb up its arse. */#define NUM_EVENTS_CACHED 256static unsigned char event_send_last = 0;static unsigned char event_read_last = 0;static XEvent event_sent[NUM_EVENTS_CACHED];/* returns 0, if buffer is full, else returns 1 */int push_event (XEvent * ev){    unsigned char j = event_send_last + 1;    if (event_read_last == j) {		/* no more space */#ifdef DEBUG/* NLS ? */	fprintf (stderr, "%s:%s:%d: *Warning* event stack full\n", PACKAGE, __FILE__, __LINE__);#endif	/* we are just going to ignore this */	return 0;    }    if (ev->type == Expose || ev->type == InternalExpose) {	/* must handle expose counts also */	unsigned char i = event_send_last - 1;	XEvent *e;	j = event_read_last - 1;	ev->xexpose.count = 0;	/* this is the very last expose by definition */	while (i != j) {	/* search backwards until a similar event is found */	    if ((e = &(event_sent[i]))->xany.window == ev->xany.window) {		if (e->type == ev->type) {		    e->xexpose.count = 1;	/* we are not going to actually "count", but we must indicate if the queue isn't empty with a "1" */		    break;		}	    }	    i--;	}    }    memcpy (&event_sent[event_send_last], ev, sizeof (XEvent));    event_send_last++;    return 1;}extern int block_push_event;	/* see initapp.c *//* pops the oldest event, returns 0 if empty */int pop_event (XEvent * ev){    if (event_read_last == event_send_last)	return 0;		/* "stack" is empty */    block_push_event = 1;    memcpy (ev, &event_sent[event_read_last], sizeof (XEvent));    memset (&event_sent[event_read_last], 0, sizeof (XEvent));    event_read_last++;    block_push_event = 0;    return 1;}/* use this instead of XSextEvent to send an event to your own application */int CSendEvent (XEvent * e){    int r = 0;    block_push_event = 1;    r = push_event (e);    block_push_event = 0;    return r;}/* sends an event (type = msg) to the given widget */int CSendMessage (CWidget * w, int msg){    CEvent cwevent;    XEvent xevent;    if (!w)	return 0;    memset (&cwevent, 0, sizeof (CEvent));    memset (&xevent, 0, sizeof (XEvent));    xevent.type = cwevent.type = msg;    cwevent.kind = w->kind;    xevent.xany.window = cwevent.window = w->winid;    cwevent.ident = "";    return run_callbacks (w, &xevent, &cwevent);}int CQueueSize (){    int r = event_read_last;    int s = event_send_last;    s -= r;    if (s < 0)	return NUM_EVENTS_CACHED + s;    return s;}/* returns nonzero if pending on either internal or X queue */int CPending (){    if (CQueueSize ())	return 1;    if (XEventsQueued (CDisplay, QueuedAfterFlush))	return 1;    return 0;}/*    does checks for expose events pending, if there is one on either queue then   it removes it and returns it. */int CExposePending (Window w, XEvent * ev){    XEvent *e;    unsigned char i = event_read_last;    while (i != event_send_last) {	if ((e = &(event_sent[i]))->xany.window == w)	    if (e->type == Expose) {		memcpy (ev, e, sizeof (XEvent));		e->type = 0;		return 1;	    }	i++;    }    return XCheckWindowEvent (CDisplay, w, ExposureMask, ev);}/*    Searches the local queue for an event matching the window   and mask. Does NOT remove the event, returns non-zero if found.   a mask of 0 matches any type, only the masks below are supported:   add more masks as needed. A window of 0 matches any window.   event_return may be passed as 0 if unneeded. */int CCheckWindowEvent (Window w, long event_mask, XEvent ** event_return){    unsigned char i = event_send_last - 1;    unsigned char j = event_read_last - 1;    static XEvent e;    static long mask[CLASTEvent] =    {99};    if (!event_mask)	event_mask = 0xFFFF;    if (mask[0] == 99) {	memset (mask, 0, CLASTEvent * sizeof (long));	mask[KeyPress] = KeyPressMask;	mask[KeyRelease] = KeyReleaseMask;	mask[ButtonPress] = ButtonPressMask;	mask[ButtonRelease] = ButtonReleaseMask;	mask[MotionNotify] = PointerMotionMask | ButtonMotionMask;	mask[EnterNotify] = EnterWindowMask;	mask[LeaveNotify] = LeaveWindowMask;	mask[Expose] = ExposureMask;	mask[ButtonRepeat] = ButtonReleaseMask | ButtonPressMask;    }    while (i != j) {	if ((event_sent[i].xany.window == w || !w)	    && (mask[event_sent[i].type] & event_mask)) {	    if (event_return)		*event_return = &(event_sent[i]);	    return 1;	}	i--;    }    if (!w) {	if (XCheckMaskEvent (CDisplay, event_mask, &e))	    goto send_event;    } else {	if (XCheckWindowEvent (CDisplay, w, event_mask, &e))	    goto send_event;    }    return 0;  send_event:    CSendEvent (&e);    if (event_return)	*event_return = &e;    return 1;}int CKeyPending (void){    XSync (CDisplay, 0);    return CCheckWindowEvent (0, KeyPressMask, 0);}/* send an expose event via the internal queue */int CSendExpose (Window win, int x, int y, int w, int h){    XEvent e;    e.xexpose.type = Expose;    e.xexpose.serial = 0;    e.xexpose.send_event = 1;    e.xexpose.display = CDisplay;    e.xexpose.window = win;    e.xexpose.x = x;    e.xexpose.y = y;    e.xexpose.width = w;    e.xexpose.height = h;    return CSendEvent (&e);}/* }}} end of internal queue handler *//* {{{ here is an expose caching-amalgamating stack system */typedef struct {    short x1, y1, x2, y2;    Window w;    long error;    int count;} CRegion;    #define MAX_NUM_REGIONS 63static CRegion regions[MAX_NUM_REGIONS + 1];#define area(c) abs(((c).x1-(c).x2)*((c).y1-(c).y2))static CRegion add_regions (CRegion r1, CRegion r2){    CRegion r;    r.x2 = max (max (r1.x1, r1.x2), max (r2.x1, r2.x2));    r.x1 = min (min (r1.x1, r1.x2), min (r2.x1, r2.x2));    r.y2 = max (max (r1.y1, r1.y2), max (r2.y1, r2.y2));    r.y1 = min (min (r1.y1, r1.y2), min (r2.y1, r2.y2));    r.w = r2.w;    r.error = (long) area (r) - area (r1) - area (r2);    r.error = max (r.error, 0);    r.error += r1.error + r2.error;    r.count = min (r1.count, r2.count);    return r;}/* returns 1 when the stack is full, 0 otherwise */static int push_region (XExposeEvent * e){    CRegion p;    p.x1 = e->x;    p.x2 = e->x + e->width;    p.y1 = e->y;    p.y2 = e->y + e->height;    p.w = e->window;    p.error = 0;    p.count = e->count;    if (last_region) {		/* this amalgamates p with a region on the stack of the same window */	CRegion q;	int i;	for (i = last_region - 1; i >= 0; i--) {	    if (regions[i].w == p.w) {		q = add_regions (regions[i], p);		if (q.error < 100) {		    regions[i] = q;	/* amalgamate region, else... */		    return 0;		}	    }	}    }    regions[last_region++] = p;		/* ...store a completely new region */    if (last_region >= MAX_NUM_REGIONS) {/* NLS ? */	printf ("push_region(): last_region >= MAX_NUM_REGIONS\n");	return 1;    }    return 0;}/*   Pops the first region matching w, if w == 0 then pops    the first region, returns 1 on empty. */static int pop_region (XExposeEvent * e, Window w){    e->type = 0;    if (last_region) {	int i = 0;	if (w == 0)	    goto any_window;	for (i = last_region - 1; i >= 0; i--) {	    if (regions[i].w == w) {	      any_window:;		e->type = Expose;		e->serial = e->send_event = 0;		e->display = CDisplay;		e->window = regions[i].w;		e->x = min (regions[i].x1, regions[i].x2);		e->y = min (regions[i].y1, regions[i].y2);		e->width = abs (regions[i].x1 - regions[i].x2);		e->height = abs (regions[i].y1 - regions[i].y2);		e->count = regions[i].count;		last_region--;		memmove (&(regions[i]), &(regions[i + 1]), (last_region - i) * sizeof (CRegion));		return 0;	    }	}    }    return 1;}static void pop_all_regions (Window w){    XEvent e;    while (!pop_region (&(e.xexpose), w)) {	e.type = InternalExpose;	CSendEvent (&e);    }}/* }}} end expose amalgamation stack system *//* {{{ key conversion utilities *//* xim.c */KeySym key_sym_xlat (XEvent * ev, char *x_lat);KeySym CKeySym (XEvent * e){    return key_sym_xlat (e, 0);}int mod_type_key (KeySym x){    switch ((int) x) {#ifdef XK_Shift_L    case XK_Shift_L:#endif#ifdef XK_Shift_R    case XK_Shift_R:#endif#ifdef XK_Control_L    case XK_Control_L:#endif#ifdef XK_Control_R    case XK_Control_R:#endif#ifdef XK_Caps_Lock    case XK_Caps_Lock:#endif#ifdef XK_Shift_Lock    case XK_Shift_Lock:#endif#ifdef XK_Meta_L    case XK_Meta_L:#endif#ifdef XK_Meta_R    case XK_Meta_R:#endif#ifdef XK_Alt_L    case XK_Alt_L:#endif#ifdef XK_Alt_R    case XK_Alt_R:#endif#ifdef XK_Super_L    case XK_Super_L:#endif#ifdef XK_Super_R    case XK_Super_R:#endif#ifdef XK_Hyper_L    case XK_Hyper_L:#endif#ifdef XK_Hyper_R    case XK_Hyper_R:#endif	return 1;    }    return 0;}/* get a 15 bit "almost unique" key sym that includes keyboard modifier   info in the top 3 bits */short CKeySymMod (XEvent * ev){    KeySym p;    XEvent e;#ifdef USE_XIM    XIC ic;#endif    int state;    if (!ev)	return 0;    e = *ev;    state = e.xkey.state;    e.xkey.state = 0;		/* want the raw key */#ifdef USE_XIM    ic = CIC;/* turn off IC 'cos we want raw translation */    CIC = 0;    p = CKeySym (&e);    CIC = ic;#else    p = CKeySym (&e);#endif    if (p && !mod_type_key (p)) {	if (state & ShiftMask)	    p ^= 0x1000;	if (state & ControlMask)	    p ^= 0x2000;	if (state & MyAltMask)	    p ^= 0x4000;	p &= 0x7FFF;    } else	p = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -