Пример #1
0
void mm_look(MazeMap *mm, const char *line, RelDir rel_dir)
{
    Dir front = TURN(mm->dir, rel_dir),
        left  = TURN(front, LEFT),
        right = TURN(front, RIGHT),
        back  = TURN(front, BACK);

    int r = mm->loc.r,
        c = mm->loc.c;

    while (*line)
    {
        bool open_left = false, open_right = false;
        switch (*line++)
        {
        case 'B':  /* opening on both sides */
            open_left = open_right = true;
            break;
        case 'L':  /* opening on left side */
            open_left = true;
            break;
        case 'R':   /* opening on right side */
            open_right = true;
            break;
        case 'N':   /* no opening on either side */
            break;
        case 'W':  /* wall immediately ahead: */
            SET_WALL(mm, r, c, front, PRESENT);
            assert(*line == '\0');
            return;
        default:  /* invalid char */
            assert(0);
        }

        push_border(mm, r, c, front);
        r = RDR(r, front);
        c = CDC(c, front);

        SET_SQUARE(mm, r, c, PRESENT);
        SET_WALL(mm, r, c, back, ABSENT);
        SET_WALL(mm, r, c, left, open_left ? ABSENT : PRESENT);
        SET_WALL(mm, r, c, right, open_right ? ABSENT : PRESENT);

        if (open_left)
        {
            SET_SQUARE(mm, RDR(r, left), CDC(c, left), PRESENT);
            push_border(mm, r, c, left);
        }

        if (open_right)
        {
            SET_SQUARE(mm, RDR(r, right), CDC(c, right), PRESENT);
            push_border(mm, r, c, right);
        }
    }

    assert(0); /* shouldn't get here: every line must end with W */
    return;
}
Пример #2
0
static void
key_clbk(enum wm_key key, enum wm_state state, void* data)
{
  assert(data);
  if(state == WM_PRESS) {
    struct rdr_term* term = data;
    if(key == WM_KEY_ESC) {
      g_exit = 1;
    } else if(key == WM_KEY_ENTER) {
      RDR(term_write_return(term));
    } else if(key == WM_KEY_BACKSPACE) {
      RDR(term_write_backspace(term));
    } else if(key == WM_KEY_TAB) {
      RDR(term_write_tab(term));
    } else if(key == WM_KEY_DEL) {
      RDR(term_write_suppr(term));
    } else if(key == WM_KEY_RIGHT) {
      RDR(term_translate_cursor(term, 1));
    } else if(key == WM_KEY_LEFT) {
      RDR(term_translate_cursor(term, -1));
    } else if(key == WM_KEY_END) {
      RDR(term_translate_cursor(term, INT_MAX));
    } else if(key == WM_KEY_HOME) {
      RDR(term_translate_cursor(term, -INT_MAX));
    }  
  }
}
Пример #3
0
static Point explore(MazeMap *mm)
{
    Point res;
    int r, c, dir;
    int best_v = 0, best_dist = 0;
    for (r = 0; r < HEIGHT; ++r)
    {
        for (c = 0; c < WIDTH; ++c)
        {
            if (dist[r][c] != -1)
            {
                int v = 0;
                for (dir = 0; dir < 4; ++dir)
                {
                    if (SQUARE(mm, RDR(r, dir), CDC(c, dir)) == UNKNOWN &&
                        WALL(mm, r, c, dir) != PRESENT) ++v;
                }
                if (v > best_v || (v == best_v && dist[r][c] < best_dist))
                {
                    best_v = v;
                    best_dist = dist[r][c];
                    res.r = r;
                    res.c = c;
                }
            }
        }
    }
    assert(best_v > 0);
    return res;
}
Пример #4
0
static void
term_char_clbk(wchar_t wch, enum wm_state state, void* data)
{
  struct app* app = data;
  enum app_error app_err = APP_NO_ERROR;
  const char ch = (char)wch;
  assert(data);

  if(state != WM_PRESS || wch > 126 || wch < 32)
    goto exit;

  app_err = app_command_buffer_write_char(app->term.cmdbuf, ch);
  if(APP_NO_ERROR != app_err) {
    APP_PRINT_ERR
      (app->logger,
       "command buffer input error: `%s'\n",
       app_error_string(app_err));
    goto error;
  }
  RDR(term_print_wchar
    (app->term.render_term,
     RDR_TERM_CMDOUT,
     wch,
     RDR_TERM_COLOR_WHITE));
exit:
  return;
error:
  goto exit;
}
Пример #5
0
static bool mark_dead_end(MazeMap *mm, bool dead_end[HEIGHT][WIDTH],
                          int r, int c)
{
    int num_walls = 0, num_dead_adjacent = 0, dir;
    bool changed = false;

    if (dead_end[r][c]) return false;

    for (dir = 0; dir < 4; ++dir)
    {
        int w = WALL(mm, r, c, dir);
        if (w == PRESENT)
            ++num_walls;
        else
        if (w == ABSENT && dead_end[RDR(r, dir)][CDC(c, dir)])
            ++num_dead_adjacent;
    }
    assert(num_walls + num_dead_adjacent < 4);

    if (num_walls + num_dead_adjacent == 3)
    {
        dead_end[r][c] = true;
        if (SQUARE(mm, r, c) == UNKNOWN)
        {
            SET_SQUARE(mm, r, c, PRESENT);
            changed = true;
        }
        for (dir = 0; dir < 4; ++dir)
        {
            if (WALL(mm, r, c, dir) == UNKNOWN)
            {
                SET_WALL(mm, r, c, dir, ABSENT);
                changed = true;
            }
        }
        for (dir = 0; dir < 4; ++dir)
        {
            if (WALL(mm, r, c, dir) == ABSENT)
            {
                if (mark_dead_end(mm, dead_end, RDR(r, dir), CDC(c, dir)))
                    changed = true;
            }
        }
    }

    return changed;
}
Пример #6
0
static void
char_clbk(wchar_t ch, enum wm_state state, void* data)
{
  assert(data);
  if(state == WM_PRESS) {
    struct rdr_term* term = data;
    if(ch >= FIRST_CHAR && ch <= LAST_CHAR)
      RDR(term_print_wchar(term, RDR_TERM_CMDOUT, ch, RDR_TERM_COLOR_WHITE));
  }
}
Пример #7
0
void mm_move(MazeMap *mm, char move)
{
    RelDir rel_dir;
    switch (move)
    {
    case 'F': rel_dir = FRONT; break;
    case 'T': rel_dir = BACK;  break;
    case 'L': rel_dir = LEFT;  break;
    case 'R': rel_dir = RIGHT; break;
    default: assert(0);   /* invalid char */
    }
    mm->dir = TURN(mm->dir, rel_dir);
    push_border(mm, mm->loc.r, mm->loc.c, mm->dir);
    mm->loc.r = RDR(mm->loc.r, mm->dir);
    mm->loc.c = CDC(mm->loc.c, mm->dir);
    SET_SQUARE(mm, mm->loc.r, mm->loc.c, PRESENT);
}
Пример #8
0
enum app_error
app_shutdown_term(struct app* app)
{
  enum app_error app_err = APP_NO_ERROR;
  if(!app) {
    app_err = APP_INVALID_ARGUMENT;
    goto error;
  }
  if(app->term.cmdbuf)
    APP(regular_command_buffer_ref_put(app->term.cmdbuf));
  if(app->term.render_term)
    RDR(term_ref_put(app->term.render_term));
  if(true == app->term.is_enabled)
    APP(enable_term(app, false));
  memset(&app->term, 0, sizeof(app->term));

exit:
  return app_err;
error:
  goto exit;
}
Пример #9
0
/*******************************************************************************
 *
 * Helper functions.
 *
 ******************************************************************************/
static void
command_completion(struct term* term)
{
  struct app* app = NULL;
  const char* cmdbuf = NULL;
  const char** list = NULL;
  size_t cursor = 0;
  size_t len = 0;
  assert(term);

  app = CONTAINER_OF(term, struct app, term);

  APP(command_buffer_completion(app->term.cmdbuf, &len, &list));
  APP(get_command_buffer_string(app->term.cmdbuf, &cursor, &cmdbuf));
  RDR(clear_term(app->term.render_term, RDR_TERM_CMDOUT));
  RDR(term_print_string
    (app->term.render_term, RDR_TERM_CMDOUT, cmdbuf, RDR_TERM_COLOR_WHITE));
  RDR(term_translate_cursor(app->term.render_term, INT_MIN));
  RDR(term_translate_cursor(app->term.render_term, cursor));
  if(0 != len) {
    if(1 < len) {
      size_t i = 0;
      for(i = 0; i < len; ++i) {
        if(0 != i) {
          RDR(term_print_wchar
            (app->term.render_term,
             RDR_TERM_STDOUT,
             L'\t',
             RDR_TERM_COLOR_WHITE));
        }
        RDR(term_print_string
          (app->term.render_term,
           RDR_TERM_STDOUT,
           list[i],
           RDR_TERM_COLOR_WHITE));
      }
      RDR(term_print_wchar
        (app->term.render_term, RDR_TERM_STDOUT, L'\n', RDR_TERM_COLOR_WHITE));
    }
  }
}
Пример #10
0
void
icmp6_print(const u_char *bp, u_int length, const u_char *bp2)
{
	register const struct icmp6_hdr *dp;
	register const struct ip6_hdr *ip;
	register const char *str;
	register const struct ip6_hdr *oip;
	register const struct udphdr *ouh;
	register int hlen, dport;
	register const u_char *ep;
	char buf[256];
	int icmp6len;

#if 0
#define TCHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) goto trunc
#endif

	dp = (struct icmp6_hdr *)bp;
	ip = (struct ip6_hdr *)bp2;
	oip = (struct ip6_hdr *)(dp + 1);
	str = buf;
	/* 'ep' points to the end of avaible data. */
	ep = snapend;
	if (ip->ip6_plen)
		icmp6len = (ntohs(ip->ip6_plen) + sizeof(struct ip6_hdr) -
			    (bp - bp2));
	else			/* XXX: jumbo payload case... */
		icmp6len = snapend - bp;

#if 0
        (void)printf("%s > %s: ",
		ip6addr_string(&ip->ip6_src),
		ip6addr_string(&ip->ip6_dst));
#endif

	TCHECK(dp->icmp6_code);
	switch (dp->icmp6_type) {
	case ICMP6_DST_UNREACH:
		TCHECK(oip->ip6_dst);
		switch (dp->icmp6_code) {
		case ICMP6_DST_UNREACH_NOROUTE:
			printf("icmp6: %s unreachable route",
			       ip6addr_string(&oip->ip6_dst));
			break;
		case ICMP6_DST_UNREACH_ADMIN:
			printf("icmp6: %s unreachable prohibited",
			       ip6addr_string(&oip->ip6_dst));
			break;
#ifdef ICMP6_DST_UNREACH_BEYONDSCOPE
		case ICMP6_DST_UNREACH_BEYONDSCOPE:
#else
		case ICMP6_DST_UNREACH_NOTNEIGHBOR:
#endif
			printf("icmp6: %s beyond scope of source address %s",
			       ip6addr_string(&oip->ip6_dst),
			       ip6addr_string(&oip->ip6_src));
			break;
		case ICMP6_DST_UNREACH_ADDR:
			printf("icmp6: %s unreachable address",
			       ip6addr_string(&oip->ip6_dst));
			break;
		case ICMP6_DST_UNREACH_NOPORT:
			TCHECK(oip->ip6_nxt);
			hlen = sizeof(struct ip6_hdr);
			ouh = (struct udphdr *)(((u_char *)oip) + hlen);
			TCHECK(ouh->uh_dport);
			dport = ntohs(ouh->uh_dport);
			switch (oip->ip6_nxt) {
			case IPPROTO_TCP:
				printf("icmp6: %s tcp port %s unreachable",
					ip6addr_string(&oip->ip6_dst),
					tcpport_string(dport));
				break;
			case IPPROTO_UDP:
				printf("icmp6: %s udp port %s unreachable",
					ip6addr_string(&oip->ip6_dst),
					udpport_string(dport));
				break;
			default:
				printf("icmp6: %s protocol %d port %d unreachable",
					ip6addr_string(&oip->ip6_dst),
					oip->ip6_nxt, dport);
				break;
			}
			break;
		default:
			printf("icmp6: %s unreachable code-#%d",
				ip6addr_string(&oip->ip6_dst),
				dp->icmp6_code);
			break;
		}
		break;
	case ICMP6_PACKET_TOO_BIG:
		TCHECK(dp->icmp6_mtu);
		printf("icmp6: too big %u", (u_int32_t)ntohl(dp->icmp6_mtu));
		break;
	case ICMP6_TIME_EXCEEDED:
		TCHECK(oip->ip6_dst);
		switch (dp->icmp6_code) {
		case ICMP6_TIME_EXCEED_TRANSIT:
			printf("icmp6: time exceeded in-transit for %s",
				ip6addr_string(&oip->ip6_dst));
			break;
		case ICMP6_TIME_EXCEED_REASSEMBLY:
			printf("icmp6: ip6 reassembly time exceeded");
			break;
		default:
			printf("icmp6: time exceeded code-#%d",
				dp->icmp6_code);
			break;
		}
		break;
	case ICMP6_PARAM_PROB:
		TCHECK(oip->ip6_dst);
		switch (dp->icmp6_code) {
		case ICMP6_PARAMPROB_HEADER:
			printf("icmp6: parameter problem errorneous - octet %u",
				(u_int32_t)ntohl(dp->icmp6_pptr));
			break;
		case ICMP6_PARAMPROB_NEXTHEADER:
			printf("icmp6: parameter problem next header - octet %u",
				(u_int32_t)ntohl(dp->icmp6_pptr));
			break;
		case ICMP6_PARAMPROB_OPTION:
			printf("icmp6: parameter problem option - octet %u",
				(u_int32_t)ntohl(dp->icmp6_pptr));
			break;
		default:
			printf("icmp6: parameter problem code-#%d",
			       dp->icmp6_code);
			break;
		}
		break;
	case ICMP6_ECHO_REQUEST:
	case ICMP6_ECHO_REPLY:
		printf("icmp6: echo %s", dp->icmp6_type == ICMP6_ECHO_REQUEST ?
		    "request" : "reply");
		if (vflag) {
			TCHECK(dp->icmp6_seq);
			printf(" (id:%04x seq:%u)",
			    ntohs(dp->icmp6_id), ntohs(dp->icmp6_seq));
		}
		break;
	case ICMP6_MEMBERSHIP_QUERY:
		printf("icmp6: multicast listener query ");
		if (length == MLD_V1_QUERY_MINLEN) {
			mld6_print((const u_char *)dp);
		} else if (length >= MLD_V2_QUERY_MINLEN) {
			printf("v2 ");
			mldv2_query_print((const u_char *)dp, length);
		} else {
			printf("unknown-version (len %u) ", length);
		}
		break;
	case ICMP6_MEMBERSHIP_REPORT:
		printf("icmp6: multicast listener report ");
		mld6_print((const u_char *)dp);
		break;
	case ICMP6_MEMBERSHIP_REDUCTION:
		printf("icmp6: multicast listener done ");
		mld6_print((const u_char *)dp);
		break;
	case ND_ROUTER_SOLICIT:
		printf("icmp6: router solicitation ");
		if (vflag) {
#define RTSOLLEN 8
		        icmp6_opt_print((const u_char *)dp + RTSOLLEN,
					icmp6len - RTSOLLEN);
		}
		break;
	case ND_ROUTER_ADVERT:
		printf("icmp6: router advertisement");
		if (vflag) {
			struct nd_router_advert *p;

			p = (struct nd_router_advert *)dp;
			TCHECK(p->nd_ra_retransmit);
			printf("(chlim=%d, ", (int)p->nd_ra_curhoplimit);
			if (p->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
				printf("M");
			if (p->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
				printf("O");
			if (p->nd_ra_flags_reserved != 0)
				printf(" ");
			printf("router_ltime=%d, ", ntohs(p->nd_ra_router_lifetime));
			printf("reachable_time=%u, ",
				(u_int32_t)ntohl(p->nd_ra_reachable));
			printf("retrans_time=%u)",
				(u_int32_t)ntohl(p->nd_ra_retransmit));
#define RTADVLEN 16
		        icmp6_opt_print((const u_char *)dp + RTADVLEN,
					icmp6len - RTADVLEN);
		}
		break;
	case ND_NEIGHBOR_SOLICIT:
	    {
		struct nd_neighbor_solicit *p;
		p = (struct nd_neighbor_solicit *)dp;
		TCHECK(p->nd_ns_target);
		printf("icmp6: neighbor sol: who has %s",
			ip6addr_string(&p->nd_ns_target));
		if (vflag) {
#define NDSOLLEN 24
		        icmp6_opt_print((const u_char *)dp + NDSOLLEN,
					icmp6len - NDSOLLEN);
		}
	    }
		break;
	case ND_NEIGHBOR_ADVERT:
	    {
		struct nd_neighbor_advert *p;

		p = (struct nd_neighbor_advert *)dp;
		TCHECK(p->nd_na_target);
		printf("icmp6: neighbor adv: tgt is %s",
			ip6addr_string(&p->nd_na_target));
                if (vflag) {
#define ND_NA_FLAG_ALL	\
	(ND_NA_FLAG_ROUTER|ND_NA_FLAG_SOLICITED|ND_NA_FLAG_OVERRIDE)
			/* we don't need ntohl() here.  see advanced-api-04. */
			if (p->nd_na_flags_reserved &  ND_NA_FLAG_ALL) {
#undef ND_NA_FLAG_ALL
				u_int32_t flags;

				flags = p->nd_na_flags_reserved;
				printf("(");
				if (flags & ND_NA_FLAG_ROUTER)
					printf("R");
				if (flags & ND_NA_FLAG_SOLICITED)
					printf("S");
				if (flags & ND_NA_FLAG_OVERRIDE)
					printf("O");
				printf(")");
			}
#define NDADVLEN 24
		        icmp6_opt_print((const u_char *)dp + NDADVLEN,
					icmp6len - NDADVLEN);
		}
	    }
		break;
	case ND_REDIRECT:
	{
#define RDR(i) ((struct nd_redirect *)(i))
		char tgtbuf[INET6_ADDRSTRLEN], dstbuf[INET6_ADDRSTRLEN];

		TCHECK(RDR(dp)->nd_rd_dst);
		inet_ntop(AF_INET6, &RDR(dp)->nd_rd_target,
			  tgtbuf, INET6_ADDRSTRLEN);
		inet_ntop(AF_INET6, &RDR(dp)->nd_rd_dst,
			  dstbuf, INET6_ADDRSTRLEN);
		printf("icmp6: redirect %s to %s", dstbuf, tgtbuf);
#define REDIRECTLEN 40
		if (vflag) {
			icmp6_opt_print((const u_char *)dp + REDIRECTLEN,
					icmp6len - REDIRECTLEN);
		}
		break;
	}
	case ICMP6_ROUTER_RENUMBERING:
		switch (dp->icmp6_code) {
		case ICMP6_ROUTER_RENUMBERING_COMMAND:
			printf("icmp6: router renum command");
			break;
		case ICMP6_ROUTER_RENUMBERING_RESULT:
			printf("icmp6: router renum result");
			break;
		default:
			printf("icmp6: router renum code-#%d", dp->icmp6_code);
			break;
		}
		break;
#ifdef ICMP6_WRUREQUEST
	case ICMP6_WRUREQUEST:	/*ICMP6_FQDN_QUERY*/
	    {
		int siz;
		siz = ep - (u_char *)(dp + 1);
		if (siz == 4)
			printf("icmp6: who-are-you request");
		else {
			printf("icmp6: FQDN request");
			if (vflag) {
				if (siz < 8)
					printf("?(icmp6_data %d bytes)", siz);
				else if (8 < siz)
					printf("?(extra %d bytes)", siz - 8);
			}
		}
		break;
	    }
#endif /*ICMP6_WRUREQUEST*/
#ifdef ICMP6_WRUREPLY
	case ICMP6_WRUREPLY:	/*ICMP6_FQDN_REPLY*/
	    {
		enum { UNKNOWN, WRU, FQDN } mode = UNKNOWN;
		u_char const *buf;
		u_char const *cp = NULL;

		buf = (u_char *)(dp + 1);

		/* fair guess */
		if (buf[12] == ep - buf - 13)
			mode = FQDN;
		else if (dp->icmp6_code == 1)
			mode = FQDN;

		/* wild guess */
		if (mode == UNKNOWN) {
			cp = buf + 4;
			while (cp < ep) {
				if (!isprint(*cp++))
					mode = FQDN;
			}
		}
#ifndef abs
#define abs(a)	((0 < (a)) ? (a) : -(a))
#endif
		if (mode == UNKNOWN && 2 < abs(buf[12] - (ep - buf - 13)))
			mode = WRU;
		if (mode == UNKNOWN)
			mode = FQDN;

		if (mode == WRU) {
			cp = buf + 4;
			printf("icmp6: who-are-you reply(\"");
		} else if (mode == FQDN) {
			cp = buf + 13;
			printf("icmp6: FQDN reply(\"");
		}
		for (; cp < ep; cp++)
			printf((isprint(*cp) ? "%c" : "\\%03o"), *cp);
		printf("\"");
		if (vflag) {
			printf(",%s", mode == FQDN ? "FQDN" : "WRU");
			if (mode == FQDN) {
				int ttl;
				ttl = (int)ntohl(*(u_int32_t *)&buf[8]);
				if (dp->icmp6_code == 1)
					printf(",TTL=unknown");
				else if (ttl < 0)
					printf(",TTL=%d:invalid", ttl);
				else
					printf(",TTL=%d", ttl);
				if (buf[12] != ep - buf - 13) {
					(void)printf(",invalid namelen:%d/%u",
						buf[12],
						(unsigned int)(ep - buf - 13));
				}
			}
		}
		printf(")");
		break;
	    }
#endif /*ICMP6_WRUREPLY*/
	case MLDV2_LISTENER_REPORT:
		printf("multicast listener report v2");
		mldv2_report_print((const u_char *) dp, length);
		break;
	default:
		printf("icmp6: type-#%d", dp->icmp6_type);
		break;
	}
	if (vflag) {
		u_int16_t sum;
		if (TTEST2(dp->icmp6_type, length)) {
			sum = icmp6_cksum(ip, dp, length);
			if (sum != 0)
				printf(" [bad icmp6 cksum %x!]", sum);
			else
				printf(" [icmp6 cksum ok]");
		}
	}
	return;
trunc:
	fputs("[|icmp6]", stdout);
#if 0
#undef TCHECK
#endif
}
Пример #11
0
static void
term_key_clbk(enum wm_key key, enum wm_state state, void* data)
{
  const char* cstr = NULL;
  struct term* term = NULL;
  enum app_error app_err = APP_NO_ERROR;
  size_t cursor = 0;
  assert(data);

  if(state != WM_PRESS)
    return;

  term = &((struct app*)data)->term;
  switch(key) {
    case WM_KEY_ENTER:
      RDR(term_write_return(term->render_term));
      app_err = app_execute_command_buffer(term->cmdbuf);
      assert(APP_COMMAND_ERROR == app_err || APP_NO_ERROR == app_err);
      break;
    case WM_KEY_BACKSPACE:
      RDR(term_write_backspace(term->render_term));
      APP(command_buffer_write_backspace(term->cmdbuf));
      break;
    case WM_KEY_DEL:
      RDR(term_write_suppr(term->render_term));
      APP(command_buffer_write_suppr(term->cmdbuf));
      break;
    case WM_KEY_RIGHT:
      RDR(term_translate_cursor(term->render_term, 1));
      APP(command_buffer_move_cursor(term->cmdbuf, 1));
      break;
    case WM_KEY_LEFT:
      RDR(term_translate_cursor(term->render_term, -1));
      APP(command_buffer_move_cursor(term->cmdbuf, -1));
      break;
    case WM_KEY_END:
      RDR(term_translate_cursor(term->render_term, INT_MAX));
      APP(command_buffer_move_cursor(term->cmdbuf, INT_MAX));
      break;
    case WM_KEY_HOME:
      RDR(term_translate_cursor(term->render_term, INT_MIN));
      APP(command_buffer_move_cursor(term->cmdbuf, INT_MIN));
      break;
    case WM_KEY_UP:
    case WM_KEY_DOWN:
      if(WM_KEY_UP == key ) {
        APP(command_buffer_history_next(term->cmdbuf));
      } else {
        APP(command_buffer_history_prev(term->cmdbuf));
      }
      APP(get_command_buffer_string(term->cmdbuf, &cursor, &cstr));
      RDR(clear_term(term->render_term, RDR_TERM_CMDOUT));
      RDR(term_print_string
       (term->render_term, RDR_TERM_CMDOUT, cstr, RDR_TERM_COLOR_WHITE));
      RDR(term_translate_cursor(term->render_term, INT_MIN));
      RDR(term_translate_cursor(term->render_term, cursor));
      break;
    case WM_KEY_TAB:
      command_completion(term);
      break;
    default:
      break;
  }
}
Пример #12
0
int
main(int argc, char** argv)
{
  /* Window manager data structures. */
  struct wm_device* dev = NULL;
  struct wm_window* win = NULL;
  const struct wm_window_desc win_desc = { 800, 600, 0 };
  /* Renderer data structure. */
  struct rdr_glyph_desc glyph_desc_list[NB_CHARS];
  struct rdr_font* font = NULL;
  struct rdr_frame* frame = NULL;
  struct rdr_system* sys = NULL;
  struct rdr_term* term = NULL;
  /* Resources data structure. */
  struct rsrc_context* ctxt = NULL;
  struct rsrc_font* rfont = NULL;
  /* Miscellaneous data. */
  const char* driver_name = NULL;
  const char* font_name = NULL;
  size_t line_space = 0;
  size_t i = 0;
  bool b = false;

  if(argc != 3) {
    printf("usage: %s RB_DRIVER FONT\n", argv[0]);
    return -1;
  }
  driver_name = argv[1];
  font_name = argv[2];

  /* Setup the render font. */
  RSRC(create_context(NULL, &ctxt));
  RSRC(create_font(ctxt, font_name, &rfont));
  if(RSRC(is_font_scalable(rfont, &b)), b)
    RSRC(font_size(rfont, 18, 18));

  for(i = 0; i < NB_CHARS; ++i) {
    struct rsrc_glyph* glyph = NULL;
    struct rsrc_glyph_desc glyph_desc;
    size_t width = 0;
    size_t height = 0;
    size_t Bpp = 0;
    size_t size = 0;

    RSRC(font_glyph(rfont, (wchar_t)(i + FIRST_CHAR), &glyph));

    /* Get glyph desc. */
    RSRC(glyph_desc(glyph, &glyph_desc));
    glyph_desc_list[i].width = glyph_desc.width;
    glyph_desc_list[i].character = glyph_desc.character;
    glyph_desc_list[i].bitmap_left = glyph_desc.bbox.x_min;
    glyph_desc_list[i].bitmap_top = glyph_desc.bbox.y_min;

    /* Get glyph bitmap. */
    RSRC(glyph_bitmap(glyph, true, &width, &height, &Bpp, NULL));
    glyph_desc_list[i].bitmap.width = width;
    glyph_desc_list[i].bitmap.height = height;
    glyph_desc_list[i].bitmap.bytes_per_pixel = Bpp;
    glyph_desc_list[i].bitmap.buffer = NULL;
    size = width * height * Bpp;
    if(0 != size) {
      unsigned char* buffer = MEM_CALLOC(&mem_default_allocator, 1, size);
      RSRC(glyph_bitmap(glyph, true, NULL, NULL, NULL, buffer));
      glyph_desc_list[i].bitmap.buffer = buffer;
    }

    RSRC(glyph_ref_put(glyph));
  }

  RSRC(font_line_space(rfont, &line_space));
  RSRC(font_ref_put(rfont));
  RSRC(context_ref_put(ctxt));

  WM(create_device(NULL, &dev));
  WM(create_window(dev, &win_desc, &win));

  RDR(create_system(driver_name, NULL, &sys));
  RDR(create_frame
    (sys, (struct rdr_frame_desc[]){{win_desc.width,win_desc.height}}, &frame));