Ejemplo n.º 1
0
/* This is a bit of a misnomer - this will deliver the normal events
   but it doesn't bother doing any sort of bounds checking or anything,
   we just start at the "focus" window and try to deliver events to the path
*/
void
GsDeliverRawMouseEvent(int rx, int ry, int buttons, int modifiers)
{
	int i;

	GR_WINDOW *wp;		/* current window */
	GR_CLIENT *client;	/* current client */
	GR_WINDOW_ID subwid;	/* subwindow id event is for */

	GR_EVENT_CLIENT *ecp;

	/* Start with the "focus" window and move up */
	/* Since the raw mouse position doesn't match the actual
	   geometry, this is all we can do */
	wp = mousewp;
	subwid = wp->id;

	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
		GR_EVENT_MOUSE *ep;

		if ((ecp->eventmask & GR_EVENT_MASK_MOUSE_POSITION) == 0)
			continue;

		client = ecp->client;

		GsFreePositionEvent(client, wp->id, subwid);

		ep = (GR_EVENT_MOUSE *) GsAllocEvent(client);
		if (ep == NULL)
			continue;

		ep->type = GR_EVENT_TYPE_MOUSE_POSITION;
		ep->wid = wp->id;
		ep->subwid = subwid;
		ep->rootx = rx;
		ep->rooty = ry;
		ep->x = 0;	/* These make no sense in raw mode */
		ep->y = 0;
		ep->buttons = buttons;
		ep->modifiers = modifiers;

		if ((wp == rootwp)
		    || (wp->nopropmask & GR_EVENT_MASK_MOUSE_POSITION))
			break;

		wp = wp->parent;
	}

	/* Deliver button events if we have to */
	for (i = 0; i < 2; i++) {
		GR_EVENT_BUTTON *gp;
		unsigned long cbuttons = 0;
		GR_EVENT_TYPE etype = (i == 0) ? GR_EVENT_TYPE_BUTTON_DOWN :
			GR_EVENT_TYPE_BUTTON_UP;

		if (i == 0)
			cbuttons = (curbuttons & ~buttons);
		else
			cbuttons = (~buttons & curbuttons);
		if (!cbuttons)
			continue;

		wp = mousewp;
		subwid = wp->id;

		for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
			client = ecp->client;

			if ((ecp->eventmask & GR_EVENTMASK(etype)) == 0)
				continue;

			gp = (GR_EVENT_BUTTON *) GsAllocEvent(ecp->client);

			if (gp == NULL)
				continue;

			gp->type = etype;
			gp->wid = wp->id;
			gp->subwid = subwid;
			gp->rootx = rx;
			gp->rooty = ry;
			gp->x = 0;
			gp->y = 0;
			gp->buttons = buttons;
			gp->changebuttons = cbuttons;
			gp->modifiers = modifiers;
			gp->time = GsGetTickCount();

			if ((wp == rootwp) || (wp->nopropmask & GR_EVENTMASK(etype)))
				break;

			wp = wp->parent;
		}
	}

	curbuttons = buttons;
}
Ejemplo n.º 2
0
/*
 * Initialize the graphics and mouse devices at startup.
 * Returns nonzero with a message printed if the initialization failed.
 */
int
GsInitialize(void)
{
	GR_WINDOW	*wp;		/* root window */
	PSD		psd;
	GR_CURSOR_ID	cid;
	static MWIMAGEBITS cursorbits[16] = {
	      0xe000, 0x9800, 0x8600, 0x4180,
	      0x4060, 0x2018, 0x2004, 0x107c,
	      0x1020, 0x0910, 0x0988, 0x0544,
	      0x0522, 0x0211, 0x000a, 0x0004
	};
	static MWIMAGEBITS cursormask[16] = {
	      0xe000, 0xf800, 0xfe00, 0x7f80,
	      0x7fe0, 0x3ff8, 0x3ffc, 0x1ffc,
	      0x1fe0, 0x0ff0, 0x0ff8, 0x077c,
	      0x073e, 0x021f, 0x000e, 0x0004
	};

	/* If needed, initialize the server mutex. */
	SERVER_LOCK_INIT();

	setbuf(stdout, NULL);
	setbuf(stderr, NULL);

	wp = (GR_WINDOW *) malloc(sizeof(GR_WINDOW));
	if (wp == NULL) {
		EPRINTF("Cannot allocate root window\n");
		return -1;
	}

	startTicks = GsGetTickCount();

#ifndef MW_NOSIGNALS
	/* catch terminate signal to restore tty state*/
	signal(SIGTERM, (void *)GsTerminate);
#endif

#if MW_FEATURE_TIMERS
	screensaver_delay = 0;
#endif
	screensaver_active = GR_FALSE;

	selection_owner.wid = 0;
	selection_owner.typelist = NULL;

#if !NONETWORK
#ifndef MW_NOSIGNALS
	/* ignore pipe signal, sent when clients exit*/
	signal(SIGPIPE, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
#endif

	if (GsOpenSocket() < 0) {
		EPRINTF("Cannot bind to named socket\n");
		free(wp);
		return -1;
	}
#endif

	if ((keyb_fd = GdOpenKeyboard()) == -1) {
		EPRINTF("Cannot initialise keyboard\n");
		/*GsCloseSocket();*/
		free(wp);
		return -1;
	}

#ifdef MW_FEATURE_TWO_KEYBOARDS
	if ((keyb2_fd = GdOpenKeyboard2()) == -1) {
		EPRINTF("Cannot initialise second keyboard\n");
		/*GsCloseSocket();*/
		free(wp);
		return -1;
	}
#endif

	if ((psd = GdOpenScreen()) == NULL) {
		EPRINTF("Cannot initialise screen\n");
		/*GsCloseSocket();*/
		GdCloseKeyboard();
		free(wp);
		return -1;
	}
	GdSetPortraitMode(psd, portraitmode);

	if ((mouse_fd = GdOpenMouse()) == -1) {
		EPRINTF("Cannot initialise mouse\n");
		/*GsCloseSocket();*/
		GdCloseScreen(psd);
		GdCloseKeyboard();
		free(wp);
		return -1;
	}

	/*
	 * Create std font.
	 */
#if (HAVE_BIG5_SUPPORT | HAVE_GB2312_SUPPORT | HAVE_JISX0213_SUPPORT | HAVE_KSC5601_SUPPORT)
	/* system fixed font looks better when mixed with builtin fixed fonts*/
	stdfont = GdCreateFont(psd, MWFONT_SYSTEM_FIXED, 0, NULL);
#else
	stdfont = GdCreateFont(psd, MWFONT_SYSTEM_VAR, 0, NULL);
#endif

	/*
	 * Initialize the root window.
	 */
	wp->psd = psd;
	wp->id = GR_ROOT_WINDOW_ID;
	wp->parent = NULL;		/* changed: was = NULL*/
	wp->owner = NULL;
	wp->children = NULL;
	wp->siblings = NULL;
	wp->next = NULL;
	wp->x = 0;
	wp->y = 0;
	wp->width = psd->xvirtres;
	wp->height = psd->yvirtres;
	wp->bordersize = 0;
	wp->background = BLACK;
	wp->bordercolor = wp->background;
	wp->nopropmask = 0;
	wp->bgpixmap = NULL;
	wp->bgpixmapflags = GR_BACKGROUND_TILE;
	wp->eventclients = NULL;
	wp->cursorid = 0;
	wp->mapped = GR_TRUE;
	wp->realized = GR_TRUE;
	wp->output = GR_TRUE;
	wp->props = 0;
	wp->title = NULL;
	wp->clipregion = NULL;

        listpp = NULL;
	listwp = wp;
	rootwp = wp;
	focuswp = wp;
	mousewp = wp;
	focusfixed = GR_FALSE;

	/*
	 * Initialize and position the default cursor.
	 */
	curcursor = NULL;
	cursorx = -1;
	cursory = -1;
	GdShowCursor(psd);
	GsMoveCursor(psd->xvirtres / 2, psd->yvirtres / 2);

	SERVER_UNLOCK();
	cid = GrNewCursor(16, 16, 0, 0, WHITE, BLACK, cursorbits, cursormask);
	GrSetWindowCursor(GR_ROOT_WINDOW_ID, cid);
	SERVER_LOCK();

	stdcursor = GsFindCursor(cid);

#if VTSWITCH
	MwInitVt();
	/* Check for VT change every 50 ms: */
	GdAddTimer(50, CheckVtChange, NULL);
#endif
	psd->FillRect(psd, 0, 0, psd->xvirtres-1, psd->yvirtres-1,
		GdFindColor(psd, wp->background));

	/*
	 * Tell the mouse driver some things.
	 */
	curbuttons = 0;
	GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1);
	GdMoveMouse(psd->xvirtres / 2, psd->yvirtres / 2);

	/* Force root window screen paint*/
	GsRedrawScreen();

	/*
	 * Force the cursor to appear on the screen at startup.
	 * (not required with above GsRedrawScreen)
	GdHideCursor(psd);
	GdShowCursor(psd);
	 */

	/*
	 * All done.
	 */
	connectcount = 0;
	return 0;
}
Ejemplo n.º 3
0
/*
 * Deliver a mouse button event to the clients which have selected for it.
 * Each client can only be delivered one instance of the event.  The window
 * the event is delivered for is either the smallest one containing the
 * mouse coordinates, or else one of its direct ancestors.  The lowest
 * window in that tree which has enabled for the event gets it.  This scan
 * is done independently for each client.  If a window with the correct
 * noprop mask is reached, or if no window selects for the event, then the
 * event is discarded for that client.  Special case: for the first client
 * that is enabled for both button down and button up events in a window,
 * then the pointer is implicitly grabbed by that window when a button is
 * pressed down in that window.  The grabbing remains until all buttons are
 * released.  While the pointer is grabbed, no other clients or windows can
 * receive button down or up events.
 */
void GsDeliverButtonEvent(GR_EVENT_TYPE type, int buttons, int changebuttons,
			int modifiers)
{
	GR_EVENT_BUTTON	*ep;		/* mouse button event */
	GR_WINDOW	*wp;		/* current window */
	GR_EVENT_CLIENT	*ecp;		/* current event client */
	GR_CLIENT	*client;	/* current client */
	GR_WINDOW_ID	subwid;		/* subwindow id event is for */
	GR_EVENT_MASK	eventmask;	/* event mask */
	GR_EVENT_MASK	tempmask;	/* to get around compiler bug */

	eventmask = GR_EVENTMASK(type);
	if (eventmask == 0)
		return;

	/*
	 * If the pointer is implicitly grabbed, then the only window
	 * which can receive button events is that window.  Otherwise
	 * the window the pointer is in gets the events.  Determine the
	 * subwindow by seeing if it is a child of the grabbed button.
	 */
	wp = mousewp;
	subwid = wp->id;

	if (grabbuttonwp) {
#if 0
		while ((wp != rootwp) && (wp != grabbuttonwp))
			wp = wp->parent;
		if (wp != grabbuttonwp)
			subwid = grabbuttonwp->id;
#endif
		wp = grabbuttonwp;
	}

	for (;;) {
		for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
			if ((ecp->eventmask & eventmask) == 0)
				continue;

			client = ecp->client;

			/*
			 * If this is a button down, the buttons are not
			 * yet grabbed, and this client is enabled for both
			 * button down and button up events, then implicitly
			 * grab the window for him.
			 */
			if ((type == GR_EVENT_TYPE_BUTTON_DOWN)
				&& (grabbuttonwp == NULL))
			{
				tempmask = GR_EVENT_MASK_BUTTON_UP;
				if (ecp->eventmask & tempmask) {
					DPRINTF("nano-X: implicit grab on window %d\n", wp->id);
					grabbuttonwp = wp;
				}
			}

			ep = (GR_EVENT_BUTTON *) GsAllocEvent(client);
			if (ep == NULL)
				continue;

			ep->type = type;
			ep->wid = wp->id;
			ep->subwid = subwid;
			ep->rootx = cursorx;
			ep->rooty = cursory;
			ep->x = cursorx - wp->x;
			ep->y = cursory - wp->y;
			ep->buttons = buttons;
			ep->changebuttons = changebuttons;
			ep->modifiers = modifiers;
			ep->time = GsGetTickCount();
		}

		/*
		 * Events do not propagate if the window was grabbed.
		 * Also release the grab if the buttons are now all released,
		 * which can cause various events.
		 */
		if (grabbuttonwp) {
			if (buttons == 0) {
				DPRINTF("nano-X: implicit ungrab on window %d\n", grabbuttonwp->id);
				grabbuttonwp = NULL;
				GrMoveCursor(cursorx, cursory);
			}
			return;
		}

		if ((wp == rootwp) || (wp->nopropmask & eventmask))
			return;

		wp = wp->parent;
	}
}