Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/omero/cook.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <thread.h>
#include <fcall.h>
#include <draw.h>
#include <mouse.h>
#include <cursor.h>
#include <keyboard.h>
#include <frame.h>
#include <9p.h>
#include "cook.h"
#include "gui.h"

typedef struct Cooker Cooker;

enum {
	Tquiet	= 3000,	// timeout for quiet.
	Ttick	= 500,	// tick interval.
	Tdouble	= 500,	// timeout for double.
};

struct  Cooker{
	Channel*	m;	// raw.
	Channel*	c;	// cooked.
};

int
Mfmt(Fmt* f)
{
	Cmouse	*m;
	char*	s;

	m = va_arg(f->args, Cmouse*);
	switch(m->flag){
	case CMdouble:
		s = "d";
		break;
	default:
		s = " ";
	}
	return fmtprint(f," %s %x %P %uld", s, m->buttons, m->xy, m->msec);
}

static void
cookerthread(void* ca)
{
	Cooker*	cm = ca;
	Mouse	m, lm, m2;
	Cmouse	c;
	ulong	pressmsec;
	int	dclick, pressb;

	pressmsec = time(nil);
	memset(&m, 0, sizeof(m));
	memset(&lm, 0, sizeof(lm));
	dclick = pressb = 0;

	while(recv(cm->m, &m) >= 0){
	Sendnext:
		/* Insert no-button events between 
		 * 	click-a/rlse-a/click-b
		 */
		if (lm.buttons && m.buttons && !(lm.buttons&m.buttons)){
			c.Mouse = lm;
			c.buttons = 0;
			c.flag = 0;
			if (eventdebug > 2) edprint("sent1 %M\n", &c);
			send(cm->c, &c);
		}

		/* Flag double clicks.
		 */
		if (!lm.buttons && m.buttons){
			if (m.buttons == pressb){
				if (m.msec - pressmsec < Tdouble)
					dclick = 1;
			}
			pressb = m.buttons;
			pressmsec = m.msec;
		}
		c.flag = dclick ? CMdouble : 0;
		c.Mouse= m;
		if (!m.buttons && dclick){
			c.flag = CMdouble;
			dclick = 0;
		}

		/* Drop just-more-move events that are ready even
		 * before delivering the one we are processing.
		 * Deliver just the last position.
		 */
		while(nbrecv(cm->m, &m2) > 0){
			if (m2.buttons == m.buttons){
				c.Mouse = m2;		// ignored old.
				m = m2;
			} else {
				send(cm->c, &c);
				lm = m;
				m = m2;
				goto Sendnext;
			}
		}

		send(cm->c, &c);
		lm = m;
	}
	postnote(PNGROUP, getpid(), "mouse");
	sysfatal("mouse");
}

Channel*
cookmouse(Channel* mc)
{
	Cooker*	cm;

	cm = malloc(sizeof(Cooker));
	cm->m = mc;
	cm->c  = chancreate(sizeof(Cmouse), 32);
	threadcreate(cookerthread, cm, 8*1024);
	return cm->c;
}

int
cookclick(Cmouse* m, Channel* mc)
{
	int	b;

	b = m->buttons;
	do {
		recv(mc, m);
	} while(m->buttons == b);
	if (m->buttons == 0)
		return 1;
	do {
		recv(mc, m);
	} while(m->buttons != 0);
	return 0;
}

int
cookslide(Cmouse* m, Channel* mc)
{
	int	b;

	b = m->buttons;
	while(m->buttons == b){
		recv(mc, m);
	}
	if (m->buttons == 0)
		return 1;
	do {
		recv(mc, m);
	} while(m->buttons != 0);
	return 0;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.