Example #1
0
/*
 * Handle all mouse events.  These are mouse enter, mouse exit, mouse
 * motion, mouse position, button down, and button up.  This also moves
 * the cursor to the new mouse position and changes it shape if needed.
 */
void GsHandleMouseStatus(GR_COORD newx, GR_COORD newy, BUTTON newbuttons)
{
	BUTTON	changebuttons;	/* buttons that have changed */
	unsigned char	ch;		/* latest character */
	MODIFIER	modifiers;	/* latest modifiers */

	GdReadKeyboard(&ch, &modifiers); /* Read the modifiers */

	/*
	 * First, if the mouse has moved, then position the cursor to the
	 * new location, which will send mouse enter, mouse exit, focus in,
	 * and focus out events if needed.  Check here for mouse motion and
	 * mouse position events.  Flush the device queue to make sure the
	 * new cursor location is quickly seen by the user.
	 */
	if ((newx != cursorx) || (newy != cursory)) {
		GsMoveCursor(newx, newy);
		GsFlush();
		GsDeliverMotionEvent(GR_EVENT_TYPE_MOUSE_MOTION,
			newbuttons, modifiers);
		GsDeliverMotionEvent(GR_EVENT_TYPE_MOUSE_POSITION,
			newbuttons, modifiers);
	}

	/*
	 * Next, generate a button up event if any buttons have been released.
	 */
	changebuttons = (curbuttons & ~newbuttons);
	if (changebuttons) {
		GsDeliverButtonEvent(GR_EVENT_TYPE_BUTTON_UP,
			newbuttons, changebuttons, modifiers);
	}

	/*
	 * Finally, generate a button down event if any buttons have been
	 * pressed.
	 */
	changebuttons = (~curbuttons & newbuttons);
	if (changebuttons) {
		GsDeliverButtonEvent(GR_EVENT_TYPE_BUTTON_DOWN,
			newbuttons, changebuttons, modifiers);
	}

	curbuttons = newbuttons;
}
Example #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 */
	static IMAGEBITS cursorbits[16] = {
	      0xe000, 0x9800, 0x8600, 0x4180,
	      0x4060, 0x2018, 0x2004, 0x107c,
	      0x1020, 0x0910, 0x0988, 0x0544,
	      0x0522, 0x0211, 0x000a, 0x0004
	};
	static IMAGEBITS cursormask[16] = {
	      0xe000, 0xf800, 0xfe00, 0x7f80,
	      0x7fe0, 0x3ff8, 0x3ffc, 0x1ffc,
	      0x1fe0, 0x0ff0, 0x0ff8, 0x077c,
	      0x073e, 0x021f, 0x000e, 0x0004
	};

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

#if !NONETWORK
	if (GsOpenSocket() < 0) {
		perror("Cannot bind to named socket");
		free(wp);
		return -1;
	}
#endif

	if ((keyb_fd = GdOpenKeyboard()) < 0) {
		perror("Cannot initialise keyboard");
		/*GsCloseSocket();*/
		free(wp);
		return -1;
	}

	if (GdOpenScreen() < 0) {
		perror("Cannot initialise screen");
		/*GsCloseSocket();*/
		GdCloseKeyboard();
		free(wp);
		return -1;
	}

	if ((mouse_fd = GdOpenMouse()) == -1) { /* -2 == mou_nul.c */
		perror("Cannot initialise mouse");
		/*GsCloseSocket();*/
		GdCloseScreen();
		GdCloseKeyboard();
		free(wp);
		return -1;
	}

	/*
	 * Get screen dimensions for our own and the client's use,
	 * and the information about the default font.
	 */
	GdGetScreenInfo(&scrdev, &sinfo);
	GdGetFontInfo(&scrdev, FONT_OEM_FIXED, &curfont);
	GdGetModifierInfo(&sinfo.modifiers);
	GdGetButtonInfo(&sinfo.buttons);

	/*
	 * Initialize the root window.
	 */
	wp->id = GR_ROOT_WINDOW_ID;
	wp->parent = wp;
	wp->children = NULL;
	wp->siblings = NULL;
	wp->next = NULL;
	wp->x = 0;
	wp->y = 0;
	wp->width = sinfo.cols;
	wp->height = sinfo.rows;
	wp->bordersize = 0;
	wp->background = BLACK;
	wp->bordercolor = BLACK;
	wp->nopropmask = 0;
	wp->eventclients = NULL;
	wp->cursor = NULL;
	wp->mapped = GR_TRUE;
	wp->unmapcount = 0;
	wp->output = GR_TRUE;

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

	/*
	 * Initialize and position the default cursor.
	 */
	curcursor = NULL;
	cursorx = -1;
	cursory = -1;
	GsMoveCursor(sinfo.cols / 2, sinfo.rows / 2);
	GsSetCursor(GR_ROOT_WINDOW_ID, 16, 16, 0, 0, WHITE, BLACK,
		cursorbits, cursormask);

#if FRAMEBUFFER | BOGL
	fb_InitVt();
#endif
	scrdev.FillRect(&scrdev, 0, 0, sinfo.cols-1, sinfo.rows-1,
		GdFindColor(BLACK));

	/*
	 * Finally tell the mouse driver some things.
	 */
	curbuttons = 0;
	/*GdSetAccelMouse(5, 3);*/
	GdRestrictMouse(0, 0, sinfo.cols - 1, sinfo.rows - 1);
	GdMoveMouse(sinfo.cols / 2, sinfo.rows / 2);
	GsFlush();

	/*
	 * All done.
	 */
	connectcount = 0;
	return 0;
}
Example #3
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;
}
Example #4
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, BUTTON buttons, BUTTON changebuttons,
			MODIFIER 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) {
		while ((wp != rootwp) && (wp != grabbuttonwp))
			wp = wp->parent;
		if (wp != grabbuttonwp)
			subwid = grabbuttonwp->id;
		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)
					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;
		}

		/*
		 * 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) {
				grabbuttonwp = NULL;
				GsMoveCursor(cursorx, cursory);
				GsFlush();
			}
			return;
		}

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

		wp = wp->parent;
	}
}