$NetBSD: patch-ad,v 1.3 2011/02/09 22:51:38 rumko Exp $
$OpenBSD: patch-engine_c,v 1.1 2008/06/13 00:38:12 canacar Exp $

* DragonFly compatibility
* Patches to support PF > 4.1 taken from OpenBSD's ports.

--- engine.c.orig	2007-11-07 07:35:44 +0100
+++ engine.c	2009-11-17 00:31:46 +0100
@@ -18,11 +18,18 @@
 
 
 #include <sys/types.h>
+#ifdef __DragonFly__
+#include "queue.h"
+#else
 #include <sys/queue.h>
+#endif
 
 #include <ctype.h>
 #include <curses.h>
+#include <errno.h>
+#include <poll.h>
 #include <signal.h>
+#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -33,6 +40,10 @@
 #define MIN(a,b) (((a)<(b))?(a):(b))
 #endif
 
+#ifndef CIRCLEQ_END
+#define CIRCLEQ_END(head)	((void *)(head))
+#endif
+
 /* circular linked list of views */
 CIRCLEQ_HEAD(view_list, view_ent) view_head =
 				  CIRCLEQ_HEAD_INITIALIZER(view_head);
@@ -55,9 +66,6 @@
 
 volatile sig_atomic_t gotsig_close = 0;
 volatile sig_atomic_t gotsig_resize = 0;
-volatile sig_atomic_t gotsig_alarm = 0;
-int need_update = 0;
-int need_sort = 0;
 
 SCREEN *screen;
 
@@ -105,7 +113,6 @@
 
 int
 tbprintf(char *format, ...)
-	GCC_PRINTFLIKE(1,2)       /* defined in curses.h */
 {
 	int len;
 	va_list arg;
@@ -482,7 +489,6 @@
 	v = ve->view;
 	
 	if ((curr_view != NULL) && (curr_mgr != v->mgr)) {
-		gotsig_alarm = 1;
 		if (v->mgr != NULL && v->mgr->select_fn != NULL)
 			v->mgr->select_fn();
 	}
@@ -491,7 +497,6 @@
 	curr_view = v;
 	curr_mgr = v->mgr;
 	field_setup();
-	need_update = 1;
 }
 
 void
@@ -809,6 +814,9 @@
 {
 	order_type *o, *oc;
 
+	if (curr_view->mgr->order_list == NULL)
+		return;
+
 	oc = curr_view->mgr->order_curr;
 
 	for (o = curr_view->mgr->order_list; o->name != NULL; o++) {
@@ -905,12 +913,6 @@
 }
 
 void
-sig_alarm(int signal)
-{
-	gotsig_alarm = 1;
-}
-
-void
 setup_term(int dmax)
 {
 	max_disp = dmax;
@@ -941,8 +943,9 @@
 		keypad(stdscr, TRUE);
 		intrflush(stdscr, FALSE);
 
-		halfdelay(10);
+		cbreak();
 		noecho();
+		timeout(0);
 	}
 
 	if (dmax == 0)
@@ -970,7 +973,6 @@
 	}
 	curr_message = NULL;
 	curr_cmd = cmd;
-	need_update = 1;
 	return prev;
 }
 
@@ -987,7 +989,6 @@
 
 int
 msgprintf(char *format, ...)
-	GCC_PRINTFLIKE(1,2)       /* defined in curses.h */
 {
 	static char buf[1024];
 	int len;
@@ -1085,28 +1086,21 @@
 	if (curr_message != NULL) {
 		if (ch > 0) {
 			curr_message = NULL;
-			need_update = 1;
 		}
 	}
 
 	switch (ch) {
-	case ' ':
-		gotsig_alarm = 1;
-		break;
 	case 'o':
 		next_order();
-		need_sort = 1;
 		break;
 	case 'p':
 		paused = !paused;
-		gotsig_alarm = 1;
 		break;
 	case 'q':
 		gotsig_close = 1;
 		break;
 	case 'r':
 		sortdir *= -1;
-		need_sort = 1;
 		break;
 	case 'v':
 		/* FALLTHROUGH */
@@ -1124,49 +1118,40 @@
 		/* FALLTHROUGH */
 	case CTRL_N:
 		dispstart++;
-		need_update = 1;
 		break;
 	case KEY_UP:
 		/* FALLTHROUGH */
 	case CTRL_P:
 		dispstart--;
-		need_update = 1;
 		break;
 	case KEY_NPAGE:
 		/* FALLTHROUGH */
 	case CTRL_V:
 		dispstart += maxprint;
-		need_update = 1;
 		break;
 	case KEY_PPAGE:
 		/* FALLTHROUGH */
 	case META_V:
 		dispstart -= maxprint;
-		need_update = 1;
 		break;
 	case KEY_HOME:
 		/* FALLTHROUGH */
 	case CTRL_A:
 		dispstart = 0;
-		need_update = 1;
 		break;
 	case KEY_END:
 		/* FALLTHROUGH */
 	case CTRL_E:
 		dispstart = num_disp;
-		need_update = 1;
 		break;
 	case CTRL_L:
 		clear();
-		need_update = 1;
 		break;
 	default:
 		break;
 	}
 
-	if (set_order_hotkey(ch))
-		need_sort = 1;
-	else
+	if (!set_order_hotkey(ch))
 		set_view_hotkey(ch);
 }
 
@@ -1177,43 +1162,15 @@
 	signal(SIGINT, sig_close);
 	signal(SIGQUIT, sig_close);
 	signal(SIGWINCH, sig_resize);
-	signal(SIGALRM, sig_alarm);
 }
 
 void
 engine_loop(int countmax)
 {
+	struct pollfd set[1];
 	int count = 0;
 
 	for (;;) {
-		if (gotsig_alarm) {
-			read_view();
-			need_sort = 1;
-			gotsig_alarm = 0;
-			alarm(delay);
-		}
-
-		if (need_sort) {
-			sort_view();
-			need_sort = 0;
-			need_update = 1;
-			
-			/* XXX if sort took too long */
-			if (gotsig_alarm) {
-				gotsig_alarm = 0;
-				alarm(delay);
-			}
-		}
-
-		if (need_update) {
-			erase();
-			disp_update();
-			end_page();
-			need_update = 0;
-			if (countmax && ++count >= countmax)
-				break;
-		}
-
 		if (gotsig_close)
 			break;
 		if (gotsig_resize) {
@@ -1221,13 +1178,31 @@
 				endwin();
 			setup_term(max_disp);
 			gotsig_resize = 0;
-			need_update = 1;
 		}
 
-		if (interactive && need_update == 0)
-			keyboard();
-		else if (interactive == 0)
+		read_view();
+		sort_view();
+
+		if (rawmode == 0)
+			erase();
+		disp_update();
+		end_page();
+		if (countmax && ++count >= countmax)
+			break;
+
+		if (interactive) {
+			set[0].fd = STDIN_FILENO;
+			set[0].events = POLLIN;
+			if (poll(set, 1, delay * 1000) == -1) {
+				if (errno == EINTR)
+					continue;
+				break;
+			}
+			if ((set[0].revents & POLLIN) != 0)
+				keyboard();
+		} else {
 			sleep(delay);
+		}
 	}
 
 	if (rawmode == 0)
