📄 ctk-vncserver.c
字号:
/** * \file * The ctk-draw implementation for the CTK VNC server. * \author Adam Dunkels <adam@dunkels.com> * * *//* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the "ctk" console GUI toolkit for cc65 * * $Id: ctk-vncserver.c,v 1.5 2003/09/02 21:47:27 adamdunkels Exp $ * */#include "ctk.h"#include "ctk-draw.h"#include "dispatcher.h"#include "loader.h"#include "vnc-server.h"#include "vnc-out.h"#include "ctk-vncserver.h"#include "ctk-vncserver-conf.h"static unsigned char sizex, sizey;#define CH_ULCORNER 0x00#define CH_TITLEBAR 0x01#define CH_URCORNER 0x02#define CH_WINDOWRBORDER 0x03#define CH_LRCORNER 0x04#define CH_WINDOWLOWERBORDER 0x05#define CH_LLCORNER 0x06#define CH_WINDOWLBORDER 0x07#define CH_DIALOG_ULCORNER 0x12#define CH_DIALOGUPPERBORDER 0x09#define CH_DIALOG_URCORNER 0x0a#define CH_DIALOGRBORDER 0x0b#define CH_DIALOG_LRCORNER 0x0c#define CH_DIALOGLOWERBORDER 0x0d#define CH_DIALOG_LLCORNER 0x0e#define CH_DIALOGLBORDER 0x0f#define CH_BUTTONLEFT 0x10#define CH_BUTTONRIGHT 0x11#define CH_SEPARATOR 0x13#include "libconio.h"#define SCREENCOLOR 0#define BORDERCOLOR 1#define WIDGETCOLOR 2#define WIDGETCOLOR_FWIN 3#define WIDGETCOLOR_FOCUS 4#define WIDGETCOLOR_DIALOG 5#define WIDGETCOLOR_HLINK 6#define WIDGETCOLOR_HLINK_FOCUS 7#define WINDOWCOLOR 8#define WINDOWCOLOR_FOCUS 9#define WINDOWBORDER 10#define WINDOWBORDER_FOCUS 11#define DIALOGCOLOR 12#define OPENMENUCOLOR 13#define ACTIVEMENUITEMCOLOR 14#define MENUCOLOR 15static DISPATCHER_UIPCALL(ctk_vncserver_appcall, state);static struct dispatcher_proc p = {DISPATCHER_PROC("CTK VNC server", NULL, NULL, ctk_vncserver_appcall)};static ek_id_t id;static struct vnc_server_state conns[CTK_VNCSERVER_CONF_NUMCONNS];#define PRINTF(x) #define revers(x)/*-----------------------------------------------------------------------------------*//** * Add an update request from a client to the list of pending updates * for the connection. * * This function is called from the vnc-out module. * * \param vs The VNC connection state. * \param a The area that is requested to be updated. *//*-----------------------------------------------------------------------------------*/voidvnc_server_update_add(struct vnc_server_state *vs, struct vnc_server_update *a){ /* XXX: test both head and tail placement!*/ a->next = vs->updates_pending; vs->updates_pending = a;}/*-----------------------------------------------------------------------------------*//** * Allocate an update request from the VNC connection state. * * This function is called from the vnc-out module. * * \param vs The VNC connection state. * * \return Memory for an update structure, or NULL if no update could * be allocated. *//*-----------------------------------------------------------------------------------*/struct vnc_server_update *vnc_server_update_alloc(struct vnc_server_state *vs){ struct vnc_server_update *a; a = vs->updates_free; if(a == NULL) { return NULL; } vs->updates_free = a->next; a->next = NULL; return a;}/*-----------------------------------------------------------------------------------*//** * Deallocate an update request from the VNC connection state. * * This function is called from the vnc-out module. * * \param vs The VNC connection state. * * \param a The update structure to be deallocated. *//*-----------------------------------------------------------------------------------*/voidvnc_server_update_free(struct vnc_server_state *vs, struct vnc_server_update *a){ a->next = vs->updates_free; vs->updates_free = a;}/*-----------------------------------------------------------------------------------*//** * Dequeue the first update on the queue of updates. * * This function is called from the vnc-out module. * * \param vs The VNC connection state. * * \return The first update on the queue, or NULL if the queue is empty. *//*-----------------------------------------------------------------------------------*/struct vnc_server_update *vnc_server_update_dequeue(struct vnc_server_state *vs){ struct vnc_server_update *a; a = vs->updates_pending; if(a == NULL) { return a; } vs->updates_pending = a->next; a->next = NULL; return a;}/*-----------------------------------------------------------------------------------*//** * Remove a specific update on the queue of updates. * * \param vs The VNC connection state. * \param a The update to be removed. *//*-----------------------------------------------------------------------------------*/voidvnc_server_update_remove(struct vnc_server_state *vs, struct vnc_server_update *a){ struct vnc_server_update *b, *c; if(a == vs->updates_pending) { vs->updates_pending = a->next; } else { b = vs->updates_pending; for(c = vs->updates_pending; c != a; b = c, c = c->next); b->next = a->next; }}/*-----------------------------------------------------------------------------------*//** \internal * Flag an area to be updated for all open VNC server connections. * *//*-----------------------------------------------------------------------------------*/static voidupdate_area(u8_t x, u8_t y, u8_t w, u8_t h){ u8_t i; if(h == 0 || w == 0) { return; } /* Update for all active VNC connections. */ for(i = 0; i < CTK_VNCSERVER_CONF_NUMCONNS; ++i) { if(conns[i].state != VNC_DEALLOCATED) { vnc_out_update_area(&conns[i], x, y, w, h); } }}/*-----------------------------------------------------------------------------------*//** \internal * Allocate a VNC server connection state from the array of available * VNC connection states. *//*-----------------------------------------------------------------------------------*/static struct vnc_server_state *alloc_state(void){ u8_t i; for(i = 0; i < CTK_VNCSERVER_CONF_NUMCONNS; ++i) { if(conns[i].state == VNC_DEALLOCATED) { return &conns[i]; } } /* We are overloaded! XXX: we'll just kick all other connections! */ for(i = 0; i < CTK_VNCSERVER_CONF_NUMCONNS; ++i) { conns[i].state = VNC_DEALLOCATED; } return NULL;}/*-----------------------------------------------------------------------------------*//** \internal * Deallocate a VNC connection state. *//*-----------------------------------------------------------------------------------*/static voiddealloc_state(struct vnc_server_state *s){ s->state = VNC_DEALLOCATED;}/*-----------------------------------------------------------------------------------*/static char tmp[40];static voidcputsn(char *str, unsigned char len){ strncpy(tmp, str, len); tmp[len] = 0; cputs(tmp);}/*-----------------------------------------------------------------------------------*//** * Initialize the VNC ctk-draw module. Called by the CTK module. * *//*-----------------------------------------------------------------------------------*/voidctk_draw_init(void){ bgcolor(SCREENCOLOR); bordercolor(BORDERCOLOR); screensize(&sizex, &sizey); ctk_draw_clear(0, sizey);}/*-----------------------------------------------------------------------------------*/static voiddraw_widget(struct ctk_widget *w, unsigned char x, unsigned char y, unsigned char clipx, unsigned char clipy, unsigned char clipy1, unsigned char clipy2, unsigned char focus){ unsigned char xpos, ypos, xscroll; unsigned char i, j; unsigned char iconnum; char c, *text; unsigned char len; /* if(focus & CTK_FOCUS_WINDOW) { textcolor(WIDGETCOLOR_FWIN); if(focus & CTK_FOCUS_WIDGET) { textcolor(WIDGETCOLOR_FOCUS); } } else if(focus & CTK_FOCUS_DIALOG) { textcolor(WIDGETCOLOR_DIALOG); if(focus & CTK_FOCUS_WIDGET) { textcolor(WIDGETCOLOR_FOCUS); } } else { textcolor(WIDGETCOLOR); }*/ xpos = x + w->x; ypos = y + w->y; switch(w->type) { case CTK_WIDGET_SEPARATOR: textcolor(VNC_OUT_SEPARATORCOLOR + focus); if(ypos >= clipy1 && ypos < clipy2) { /* chlinexy(xpos, ypos, w->w);*/ gotoxy(xpos, ypos); for(i = 0; i < w->w; ++i) { cputc(CH_SEPARATOR); } } break; case CTK_WIDGET_LABEL: textcolor(VNC_OUT_LABELCOLOR + focus); text = w->widget.label.text; for(i = 0; i < w->h; ++i) { if(ypos >= clipy1 && ypos < clipy2) { gotoxy(xpos, ypos); cputsn(text, w->w); if(w->w - (wherex() - xpos) > 0) { cclear(w->w - (wherex() - xpos)); } } ++ypos; text += w->w; } break; case CTK_WIDGET_BUTTON: textcolor(VNC_OUT_BUTTONCOLOR + focus); if(ypos >= clipy1 && ypos < clipy2) { if(focus & CTK_FOCUS_WIDGET) { revers(1); } else { revers(0); } cputcxy(xpos, ypos, CH_BUTTONLEFT); cputsn(w->widget.button.text, w->w); cputc(CH_BUTTONRIGHT); revers(0); } break; case CTK_WIDGET_HYPERLINK: textcolor(VNC_OUT_HYPERLINKCOLOR + focus); if(ypos >= clipy1 && ypos < clipy2) { /* if(focus & CTK_FOCUS_WIDGET) { textcolor(WIDGETCOLOR_HLINK_FOCUS); revers(0); } else { textcolor(WIDGETCOLOR_HLINK); revers(1); }*/ gotoxy(xpos, ypos); cputsn(w->widget.button.text, w->w); revers(0); } break; case CTK_WIDGET_TEXTENTRY: textcolor(VNC_OUT_TEXTENTRYCOLOR + focus); text = w->widget.textentry.text; if(focus & CTK_FOCUS_WIDGET) { revers(1); } else { revers(0); } xscroll = 0; if(w->widget.textentry.xpos >= w->w - 1) { xscroll = w->widget.textentry.xpos - w->w + 1; } for(j = 0; j < w->h; ++j) { if(ypos >= clipy1 && ypos < clipy2) { if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT && w->widget.textentry.ypos == j) { revers(0); cputcxy(xpos, ypos, '>'); for(i = 0; i < w->w; ++i) { c = text[i + xscroll]; if(i == w->widget.textentry.xpos - xscroll) { textcolor(VNC_OUT_TEXTENTRYCOLOR + (focus ^ 0x01)); revers(1); } else { revers(0); } if(c == 0) { cputc(' '); } else { cputc(c); } revers(0); textcolor(VNC_OUT_TEXTENTRYCOLOR + focus); } cputc('<'); } else { cvlinexy(xpos, ypos, 1); gotoxy(xpos + 1, ypos); cputsn(text, w->w); i = wherex(); if(i - xpos - 1 < w->w) { cclear(w->w - (i - xpos) + 1); } cvline(1); } } ++ypos; text += w->w; } revers(0); break; case CTK_WIDGET_ICON: if(ypos >= clipy1 && ypos < clipy2) { textcolor(VNC_OUT_ICONCOLOR + focus); if(focus & 1) { revers(1); } else { revers(0); } x = xpos; len = strlen(w->widget.icon.title); if(x + len >= sizex) { x = sizex - len; } gotoxy(x, ypos + 3); if(ypos >= clipy1 && ypos < clipy2) { cputs(w->widget.icon.title); } gotoxy(xpos, ypos); if(w->widget.icon.bitmap != NULL) { iconnum = vnc_out_add_icon((struct ctk_icon *)w); gotoxy(xpos, ypos); textcolor(iconnum | (focus << 6)); cputc(0x80); cputc(0x81); cputc(0x82); cputc(0x83); ++ypos; gotoxy(xpos, ypos); cputc(0x90); cputc(0x91); cputc(0x92); cputc(0x93); ++ypos; gotoxy(xpos, ypos); cputc(0xa0); cputc(0xa1); cputc(0xa2); cputc(0xa3); ++ypos; textcolor(0); /* for(i = 0; i < 3; ++i) { if(ypos >= clipy1 && ypos < clipy2) { cputc(w->widget.icon.textmap[0 + 3 * i]); cputc(w->widget.icon.textmap[1 + 3 * i]); cputc(w->widget.icon.textmap[2 + 3 * i]); } ++ypos; }*/ } x = xpos; revers(0); } break; default: break; }}/*-----------------------------------------------------------------------------------*//** * Draw a widget on the VNC screen. Called by the CTK module. * * \param w The widget to be drawn. * \param focus The focus of the widget. * \param clipy1 The lower y coordinate bound. * \param clipy2 The upper y coordinate bound. *//*-----------------------------------------------------------------------------------*/voidctk_draw_widget(struct ctk_widget *w, unsigned char focus, unsigned char clipy1, unsigned char clipy2){ struct ctk_window *win = w->window; struct ctk_icon *icon; unsigned char posx, posy, x, len; posx = win->x + 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -