nanoxwin.c

来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 1,548 行 · 第 1/3 页

C
1,548
字号
  vfprintf(stderr, format, ap);
  va_end(ap);
}

/*****************************************************************************/
void error(char * format, ...)
{
  va_list ap;

  fprintf(stderr, "ERROR: ");
  va_start(ap, format);
  vfprintf(stderr, format, ap);
  va_end(ap);
}

/*****************************************************************************/
int rd_pstcache_mkdir(void)
{
  return 0;
}

/*****************************************************************************/
int rd_open_file(char * filename)
{
  return 0;
}

/*****************************************************************************/
void rd_close_file(int fd)
{
  return;
}

/*****************************************************************************/
int rd_read_file(int fd, void * ptr, int len)
{
  return 0;
}

/*****************************************************************************/
int rd_write_file(int fd, void * ptr, int len)
{
  return 0;
}

/*****************************************************************************/
int rd_lseek_file(int fd, int offset)
{
  return 0;
}

/*****************************************************************************/
int rd_lock_file(int fd, int start, int len)
{
  return False;
}

/*****************************************************************************/
/*static int key(int ch, int flags)
{
  return (ch & 0xffff) | ((flags & 0xffff) << 16);
}*/

/*****************************************************************************/
static void init_keys(void)
{
  memset(&g_keys, 0, sizeof(g_keys));
  g_keys[0x01].ch1 = 27; /* esc */
  g_keys[0x02].ch1 = '1';
  g_keys[0x02].chs = '!';
  g_keys[0x03].ch1 = '2';
  g_keys[0x03].chs = '@';
  g_keys[0x04].ch1 = '3';
  g_keys[0x04].chs = '#';
  g_keys[0x05].ch1 = '4';
  g_keys[0x05].chs = '$';
  g_keys[0x06].ch1 = '5';
  g_keys[0x06].chs = '%';
  g_keys[0x07].ch1 = '6';
  g_keys[0x07].chs = '^';
  g_keys[0x08].ch1 = '7';
  g_keys[0x08].chs = '&';
  g_keys[0x09].ch1 = '8';
  g_keys[0x09].chs = '*';
  g_keys[0x0a].ch1 = '9';
  g_keys[0x0a].chs = '(';
  g_keys[0x0b].ch1 = '0';
  g_keys[0x0b].chs = ')';
  g_keys[0x0c].ch1 = '-';
  g_keys[0x0c].chs = '_';
  g_keys[0x0d].ch1 = '=';
  g_keys[0x0d].chs = '+';
  g_keys[0x0e].ch1 = 8; /* backspace */
  g_keys[0x0f].ch1 = 9; /* tab */
  g_keys[0x10].ch1 = 'q';
  g_keys[0x10].chs = 'Q';
  g_keys[0x11].ch1 = 'w';
  g_keys[0x11].chs = 'W';
  g_keys[0x12].ch1 = 'e';
  g_keys[0x12].chs = 'E';
  g_keys[0x13].ch1 = 'r';
  g_keys[0x13].chs = 'R';
  g_keys[0x14].ch1 = 't';
  g_keys[0x14].chs = 'T';
  g_keys[0x15].ch1 = 'y';
  g_keys[0x15].chs = 'Y';
  g_keys[0x16].ch1 = 'u';
  g_keys[0x16].chs = 'U';
  g_keys[0x17].ch1 = 'i';
  g_keys[0x17].chs = 'I';
  g_keys[0x18].ch1 = 'o';
  g_keys[0x18].chs = 'O';
  g_keys[0x19].ch1 = 'p';
  g_keys[0x19].chs = 'P';
  g_keys[0x1a].ch1 = '[';
  g_keys[0x1a].chs = '{';
  g_keys[0x1b].ch1 = ']';
  g_keys[0x1b].chs = '}';
  g_keys[0x1c].ch2 = 13; /* enter */
  g_keys[0x1d].ch1 = 63533; /* left control */
  g_keys[0x1d].ch2 = 63534; /* right control */
  g_keys[0x1e].ch1 = 'a';
  g_keys[0x1e].chs = 'A';
  g_keys[0x1f].ch1 = 's';
  g_keys[0x1f].chs = 'S';
  g_keys[0x20].ch1 = 'd';
  g_keys[0x20].chs = 'D';
  g_keys[0x21].ch1 = 'f';
  g_keys[0x21].chs = 'F';
  g_keys[0x22].ch1 = 'g';
  g_keys[0x22].chs = 'G';
  g_keys[0x23].ch1 = 'h';
  g_keys[0x23].chs = 'H';
  g_keys[0x24].ch1 = 'j';
  g_keys[0x24].chs = 'J';
  g_keys[0x25].ch1 = 'k';
  g_keys[0x25].chs = 'K';
  g_keys[0x26].ch1 = 'l';
  g_keys[0x26].chs = 'L';
  g_keys[0x27].ch1 = ';';
  g_keys[0x27].chs = ':';
  g_keys[0x28].ch1 = '\'';
  g_keys[0x28].chs = '"';
  g_keys[0x29].ch1 = '`';
  g_keys[0x29].chs = '~';
  g_keys[0x2a].ch1 = 63531; /* left shift */
  g_keys[0x2b].ch1 = '\\';
  g_keys[0x2c].ch1 = 'z';
  g_keys[0x2c].chs = 'Z';
  g_keys[0x2d].ch1 = 'x';
  g_keys[0x2d].chs = 'X';
  g_keys[0x2e].ch1 = 'c';
  g_keys[0x2e].chs = 'C';
  g_keys[0x2f].ch1 = 'v';
  g_keys[0x2f].chs = 'V';
  g_keys[0x30].ch1 = 'b';
  g_keys[0x30].chs = 'B';
  g_keys[0x31].ch1 = 'n';
  g_keys[0x31].chs = 'N';
  g_keys[0x32].ch1 = 'm';
  g_keys[0x32].chs = 'M';
  g_keys[0x33].ch1 = ',';
  g_keys[0x33].chs = '<';
  g_keys[0x34].ch1 = '.';
  g_keys[0x34].chs = '>';
  g_keys[0x35].ch1 = '/';
  g_keys[0x35].ch2 = 63509;
  g_keys[0x35].chs = '?';
  g_keys[0x36].ch1 = 63532; /* right shift */
  g_keys[0x37].ch1 = '*'; /* star on keypad */
  g_keys[0x37].ch2 = 63510; /* star on keypad */
  g_keys[0x38].ch1 = 63535; /* alt */
  g_keys[0x38].ch2 = 63536; /* alt */
  g_keys[0x39].ch1 = ' ';
  g_keys[0x3a].ch1 = 0; /* caps lock */
  g_keys[0x3b].ch1 = 63515; /* f1 */
  g_keys[0x3c].ch1 = 63516; /* f2 */
  g_keys[0x3d].ch1 = 63517; /* f3 */
  g_keys[0x3e].ch1 = 63518; /* f4 */
  g_keys[0x3f].ch1 = 63519; /* f5 */
  g_keys[0x40].ch1 = 63520; /* f6 */
  g_keys[0x41].ch1 = 63521; /* f7 */
  g_keys[0x42].ch1 = 63522; /* f8 */
  g_keys[0x43].ch1 = 63523; /* f9 */
  g_keys[0x44].ch1 = 63524; /* f10 */
  g_keys[0x45].ch1 = 0; /* num lock */
  g_keys[0x46].ch1 = 0; /* scroll lock */
  g_keys[0x47].ch1 = 63505; /* home */
  g_keys[0x47].ch2 = 63494; /* home */
  g_keys[0x48].ch1 = 63490; /* arrow up */
  g_keys[0x48].ch2 = 63506; /* arrow up */
  g_keys[0x49].ch1 = 63507; /* page up */
  g_keys[0x49].ch2 = 63496; /* page up */
  g_keys[0x4a].ch1 = '-'; /* -(minus) on keypad */
  g_keys[0x4a].ch2 = 63511; /* -(minus) on keypad */
  g_keys[0x4b].ch1 = 63502; /* arrow left */
  g_keys[0x4b].ch2 = 63488; /* arrow left */
  g_keys[0x4c].ch1 = 63503; /* middle(5 key) on keypad */
  g_keys[0x4d].ch1 = 63504; /* arrow right */
  g_keys[0x4d].ch2 = 63489; /* arrow right */
  g_keys[0x4e].ch1 = '+'; /* +(plus) on keypad */
  g_keys[0x4e].ch2 = 63512; /* +(plus) on keypad */
  g_keys[0x4f].ch1 = 63499; /* end */
  g_keys[0x4f].ch2 = 63495; /* end */
  g_keys[0x50].ch1 = 63500; /* arrow down */
  g_keys[0x50].ch2 = 63491; /* arrow down */
  g_keys[0x51].ch1 = 63501; /* page down */
  g_keys[0x51].ch2 = 63497; /* page down */
  g_keys[0x52].ch1 = 63498; /* insert */
  g_keys[0x52].ch2 = 63492; /* insert */
  g_keys[0x53].ch1 = 63508; /* delete */
  g_keys[0x53].ch2 = 63493; /* delete */
  g_keys[0x54].ch1 = 63525; /* f11 */
  g_keys[0x54].ch1 = 63527; /* f12 */
}

/*****************************************************************************/
/* returns 0 if found key */
static int get_sc(GR_EVENT_KEYSTROKE * event_keystroke, int * sc, int * ec)
{
  int i;

  //printf("%d %d\n", event_keystroke->ch, event_keystroke->modifiers);
  *sc = 0;
  *ec = 0;
  for (i = 0; i < 256; i++)
  {
    if (event_keystroke->modifiers & 1) /* shift is down */
    {
      if (event_keystroke->ch == g_keys[i].chs)
      {
        *sc = i;
        break;
      }
    }
    if (event_keystroke->ch == g_keys[i].ch1 ||
        event_keystroke->ch == g_keys[i].ch2 ||
        event_keystroke->ch == g_keys[i].ch3)
    {
      *sc = i;
      break;
    }
  }
  if (*sc == 0)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

/*****************************************************************************/
void static process_keystroke(GR_EVENT_KEYSTROKE * event_keystroke, int down)
{
  int sc, ec;

  if (get_sc(event_keystroke, &sc, &ec) == 0)
  {
    if (down)
    {
      rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, sc, ec);
    }
    else
    {
      rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, sc, ec);
    }
  }
}

/*****************************************************************************/
void nanox_event(GR_EVENT * ev)
{
  GR_EVENT_MOUSE * event_mouse;
  GR_EVENT_BUTTON * event_button;
  GR_EVENT_FDINPUT * event_fdinput;
  GR_EVENT_KEYSTROKE * event_keystroke;

  do
  {
    if (ev->type == GR_EVENT_TYPE_FDINPUT) /* 12 */
    {
      event_fdinput = (GR_EVENT_FDINPUT *) ev;
      if (event_fdinput->fd == g_sck)
      {
        if (!rdp_loop(&g_deactivated, &g_ext_disc_reason))
        {
          fprintf(stderr, "rdp_loop in nanox_event exit codes %d %d\n",
                  g_deactivated, g_ext_disc_reason);
          exit(1);
        }
      }
    }
    else if (ev->type == GR_EVENT_TYPE_BUTTON_DOWN) /* 2 */
    {
      event_button = (GR_EVENT_BUTTON *) ev;
      if (event_button->changebuttons & 4) /* left */
      {
        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
                       event_button->x, event_button->y);
      }
      else if (event_button->changebuttons & 1) /* right */
      {
        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
                       event_button->x, event_button->y);
      }
    }
    else if (ev->type == GR_EVENT_TYPE_BUTTON_UP) /* 3 */
    {
      event_button = (GR_EVENT_BUTTON *) ev;
      if (event_button->changebuttons & 4) /* left */
      {
        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
                       event_button->x, event_button->y);
      }
      else if (event_button->changebuttons & 1) /* right */
      {
        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2,
                       event_button->x, event_button->y);
      }
    }
    else if (ev->type == GR_EVENT_TYPE_MOUSE_MOTION) /* 6 */
    {
      event_mouse = (GR_EVENT_MOUSE *) ev;
      rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,
                     event_mouse->x, event_mouse->y);
    }
    else if (ev->type == GR_EVENT_TYPE_MOUSE_POSITION) /* 7 */
    {
      /* use GR_EVENT_TYPE_MOUSE_MOTION */
    }
    else if (ev->type == GR_EVENT_TYPE_KEY_DOWN) /* 8 */
    {
      event_keystroke = (GR_EVENT_KEYSTROKE *) ev;
      process_keystroke(event_keystroke, 1);
    }
    else if (ev->type == GR_EVENT_TYPE_KEY_UP) /* 9 */
    {
      event_keystroke = (GR_EVENT_KEYSTROKE *) ev;
      process_keystroke(event_keystroke, 0);
    }
    else if (ev->type == GR_EVENT_TYPE_FOCUS_IN) /* 10 */
    {
    }
    else if (ev->type == GR_EVENT_TYPE_FOCUS_OUT) /* 11 */
    {
    }
    else if (ev->type == GR_EVENT_TYPE_UPDATE) /* 13 */
    {
    }
    GrCheckNextEvent(ev);
  } while (ev->type != GR_EVENT_TYPE_NONE);
}

/*****************************************************************************/
static void get_username_and_hostname(void)
{
  char fullhostname[64];
  char * p;
  struct passwd * pw;

  STRNCPY(g_username, "unknown", sizeof(g_username));
  STRNCPY(g_hostname, "unknown", sizeof(g_hostname));
  pw = getpwuid(getuid());
  if (pw != NULL && pw->pw_name != NULL)
  {
    STRNCPY(g_username, pw->pw_name, sizeof(g_username));
  }
  if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
  {
    p = strchr(fullhostname, '.');
    if (p != NULL)
    {
      *p = 0;
    }
    STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
  }
}
/*****************************************************************************/
static void out_params(void)
{
  fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
  fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
  fprintf(stderr, "nanox uiport by Jay Sorg\n");
  fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
  fprintf(stderr, "Usage: nanoxrdesktop [options] server\n");
  fprintf(stderr, "   -u: user name\n");
  fprintf(stderr, "   -n: client hostname\n");
  fprintf(stderr, "   -p: password\n");
  fprintf(stderr, "   -d: domain\n");
  fprintf(stderr, "   -s: shell\n");
  fprintf(stderr, "   -c: working directory\n");
  fprintf(stderr, "\n");
}

/*****************************************************************************/
static int parse_parameters(int in_argc, char ** in_argv)
{
  int i;

  if (in_argc <= 1)
  {
    out_params();
    return 0;
  }
  for (i = 1; i < in_argc; i++)
  {
    strcpy(g_servername, in_argv[i]);
    if (strcmp(in_argv[i], "-h") == 0)
    {
      out_params();
      return 0;
    }
    else if (strcmp(in_argv[i], "-n") == 0)
    {
      STRNCPY(g_hostname, in_argv[i + 1], sizeof(g_hostname));
    }
    else if (strcmp(in_argv[i], "-u") == 0)
    {
      STRNCPY(g_username, in_argv[i + 1], sizeof(g_username));
    }
    else if (strcmp(in_argv[i], "-p") == 0)
    {
      STRNCPY(g_password, in_argv[i + 1], sizeof(g_password));
      g_flags |= RDP_LOGON_AUTO;
      i++;
    }
    else if (strcmp(in_argv[i], "-d") == 0)
    {
      STRNCPY(g_domain, in_argv[i + 1], sizeof(g_domain));
      i++;
    }
    else if (strcmp(in_argv[i], "-s") == 0)
    {
      STRNCPY(g_shell, in_argv[i + 1], sizeof(g_shell));
      i++;
    }
    else if (strcmp(in_argv[i], "-c") == 0)
    {
      STRNCPY(g_directory, in_argv[i + 1], sizeof(g_directory));
      i++;
    }
  }
  return 1;
}

/*****************************************************************************/
int main(int in_argc, char ** in_argv)
{
  get_username_and_hostname();
  /* read command line options */
  if (!parse_parameters(in_argc, in_argv))
  {
    exit(0);
  }
  /* connect to server */
  if (GrOpen() < 0)
  {
    fprintf(stderr, "Couldn't connect to Nano-X server\n");
    exit(1);
  }
  GrGetScreenInfo(&g_screen_info);
  g_bpp = g_screen_info.bpp;
  g_Bpp = (g_screen_info.bpp + 7) / 8;
  g_width = g_screen_info.vs_width;
  g_height = g_screen_info.vs_height;
  g_clip.x = 0;
  g_clip.y = 0;
  g_clip.width = g_width;
  g_clip.height = g_height;
  if (!((g_bpp == 32 && g_server_bpp == 16) ||
        (g_bpp == 16 && g_server_bpp == 16)))
  {
    fprintf(stderr, "unsupported bpp, server = %d, client = %d\n",
            g_server_bpp, g_bpp);
    GrClose();
    exit(0);
  }
  init_keys();
  /* connect to server */
  if (!rdp_connect(g_servername, g_flags, g_domain, g_password, g_shell,
                   g_directory))
  {
    fprintf(stderr, "Error connecting\n");
    GrClose();
    exit(1);
  }
  /* create window */
  g_wnd = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, g_width, g_height, 0, 0, 0);
  /* show window */
  GrMapWindow(g_wnd);
  /* create graphic context */
  g_gc = GrNewGC();
  g_gc_clean = GrNewGC();
  /* clear screen */
  GrSetGCForeground(g_gc, 0);
  GrFillRect(g_wnd, g_gc, 0, 0, g_width, g_height);
  /* create null cursor */
  g_null_cursor = (GR_CURSOR_ID)ui_create_cursor(0, 0, 32, 32, 0, 0);
  /* register callbacks, set mask, and run main loop */
  GrSelectEvents(g_wnd, -1); /* all events */
  GrRegisterInput(g_sck);
  GrMainLoop(nanox_event);
  /* free null cursor */
  ui_destroy_cursor((void*)g_null_cursor);
  /* free graphic context */
  GrDestroyGC(g_gc);
  GrDestroyGC(g_gc_clean);
  /* free window */
  GrDestroyWindow(g_wnd);
  /* close connection */
  GrClose();
  return 0;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?