if (file_by_name_read_section(self->session->xrdp_ini, "Channels", names, values) == 0)
{ int chan_id; int chan_count = libxrdp_get_channel_count(self->session); constchar *disabled_str = NULL;
for (chan_id = 0 ; chan_id < chan_count ; ++chan_id)
{ char chan_name[CHANNEL_NAME_LEN + 1]; if (libxrdp_query_channel(self->session, chan_id, chan_name,
NULL) == 0)
{ int disabled = 1; /* Channels disabled if not found */ int found = 0; int index;
for (index = 0; index < names->count; index++)
{ constchar *q = (constchar *)list_get_item(names, index); constchar *r = (constchar *)list_get_item(values, index); if (g_strcasecmp(q, chan_name) == 0)
{
found = 1;
disabled = !g_text2bool(r); break;
}
} if (!found)
{
LOG(LOG_LEVEL_WARNING, "Static channel '%s' from the client" " is not named in the [Channels] section",
chan_name);
}
disabled_str = (disabled) ? "disabled" : "enabled";
LOG(LOG_LEVEL_DEBUG, "xrdp_wm_load_channel_config: " "channel %s channel id %d is %s",
chan_name, chan_id, disabled_str);
/* to store configuration from xrdp.ini, gfx.toml */
self->xrdp_config = g_new0(struct xrdp_config, 1);
self->gfx_config = g_new0(struct xrdp_tconfig_gfx, 1);
/* Load the channel config so libxrdp can check whether
drdynvc is enabled or not */
xrdp_wm_load_channel_config(self);
// Start drdynvc if available. if (libxrdp_drdynvc_start(self->session) == 0)
{ // drdynvc is started. callback() will // be notified when capabilities are received.
} elseif (self->client_info->gfx)
{
LOG(LOG_LEVEL_WARNING, "Disabling GFX as '"
DRDYNVC_SVC_CHANNEL_NAME "' isn't available");
self->client_info->gfx = 0;
}
xrdp_region_delete(self->screen_dirty_region);
xrdp_mm_delete(self->mm);
xrdp_cache_delete(self->cache);
xrdp_painter_delete(self->painter);
xrdp_bitmap_delete(self->screen); /* free the log */
list_delete(self->log); /* free default font */
xrdp_font_delete(self->default_font);
g_delete_wait_obj(self->login_state_event);
if (self->xrdp_config)
{
g_free(self->xrdp_config);
}
if (self->gfx_config)
{
g_free(self->gfx_config);
}
/* free self */
g_free(self);
}
/*****************************************************************************/ int
xrdp_wm_send_palette(struct xrdp_wm *self)
{ return libxrdp_send_palette(self->session, self->palette);
}
/*****************************************************************************/ int
xrdp_wm_send_bell(struct xrdp_wm *self)
{ return libxrdp_send_bell(self->session);
}
/*****************************************************************************/ int
xrdp_wm_send_bitmap(struct xrdp_wm *self, struct xrdp_bitmap *bitmap, int x, int y, int cx, int cy)
{ return libxrdp_send_bitmap(self->session, bitmap->width, bitmap->height,
bitmap->bpp, bitmap->data, x, y, cx, cy);
}
/******************************************************************************/ staticint
xrdp_wm_get_pixel(char *data, int x, int y, int width, int bpp)
{ int start; int shift;
/*****************************************************************************/ int
xrdp_wm_pointer(struct xrdp_wm *self, char *data, char *mask, int x, int y, int bpp, int width, int height)
{ int bytes; struct xrdp_pointer_item *pointer_item;
/*****************************************************************************/ /* returns error */ int
xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data, char *mask, int *x, int *y)
{ int fd; int len; int bpp; int w; int h; int i; int j; int pixel; int palette[16]; struct stream *fs;
if (!g_file_exist(file_name))
{
LOG(LOG_LEVEL_ERROR, "xrdp_wm_load_pointer: error pointer file [%s] does not exist",
file_name); return1;
}
if (w == 32 && h == 32)
{ if (bpp == 1)
{ for (i = 0; i < 2; i++)
{
in_uint32_le(fs, pixel);
palette[i] = pixel;
} for (i = 0; i < 32; i++)
{ for (j = 0; j < 32; j++)
{
pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)];
*data = pixel;
data++;
*data = pixel >> 8;
data++;
*data = pixel >> 16;
data++;
}
}
in_uint8s(fs, 128);
} elseif (bpp == 4)
{ for (i = 0; i < 16; i++)
{
in_uint32_le(fs, pixel);
palette[i] = pixel;
} for (i = 0; i < 32; i++)
{ for (j = 0; j < 32; j++)
{
pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)];
*data = pixel;
data++;
*data = pixel >> 8;
data++;
*data = pixel >> 16;
data++;
}
}
in_uint8s(fs, 512);
}
g_memcpy(mask, fs->p, 128); /* mask */
}
free_stream(fs); return0;
}
/*****************************************************************************/ int
xrdp_wm_send_pointer_system(struct xrdp_wm *self, int pointer_type)
{ return libxrdp_send_pointer_system(self->session, pointer_type);
}
/*****************************************************************************/ int
xrdp_wm_send_pointer_position(struct xrdp_wm *self, int x, int y)
{ return libxrdp_send_pointer_position(self->session, x, y);
}
/*****************************************************************************/ int
xrdp_wm_send_pointer(struct xrdp_wm *self, int cache_idx, char *data, char *mask, int x, int y, int bpp, int width, int height)
{ return libxrdp_send_pointer(self->session, cache_idx, data, mask,
x, y, bpp, width, height);
}
/*****************************************************************************/ int
xrdp_wm_set_pointer(struct xrdp_wm *self, int cache_idx)
{ return libxrdp_set_pointer(self->session, cache_idx);
}
/*****************************************************************************/ /* convert hex string to int */ unsignedint
xrdp_wm_htoi (constchar *ptr)
{ unsignedint value = 0; char ch = *ptr;
/*****************************************************************************/ int
xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name)
{ int bindex; int gindex; int rindex;
int fd; int index; char *val; struct list *names; struct list *values;
/* Remove a font loaded on the previous config */
xrdp_font_delete(self->default_font);
self->painter->font = NULL; /* May be set to the default_font */
/* Load the font */
dpi = xrdp_login_wnd_get_monitor_dpi(self);
self->default_font = xrdp_font_create(self, dpi);
/* Scale the login screen values */
xrdp_login_wnd_scale_config_values(self);
if (self->session->client_info->rdp_autologin)
{ /* *NOTE:thisshouldeventuallybeaccessedfromself->xrdp_config
*/
fd = g_file_open_ro(self->session->xrdp_ini); if (fd != -1)
{ struct list *names = list_create();
names->auto_free = 1; struct list *values = list_create();
values->auto_free = 1;
/* pick up the first section name except for 'globals', 'Logging', 'channels'
* in xrdp.ini and use it as default section name */
file_read_sections(fd, names);
default_section_name[0] = '\0'; for (index = 0; index < names->count; index++)
{
q = (constchar *)list_get_item(names, index); if ((g_strncasecmp("globals", q, 8) != 0) &&
(g_strncasecmp("Logging", q, 8) != 0) &&
(g_strncasecmp("LoggingPerLogger", q, 17) != 0) &&
(g_strncasecmp("channels", q, 9) != 0))
{
g_strncpy(default_section_name, q, 255); break;
}
}
/* look for module name to be loaded */ if (autorun_name[0] != 0)
{ /* if autorun is configured in xrdp.ini, we enforce that module to be loaded */
g_strncpy(section_name, autorun_name, 255);
} elseif (self->session->client_info->domain[0] != '\0' &&
self->session->client_info->domain[0] != '_')
{ /* domain names that starts with '_' are reserved for IP/DNS to
* simplify for the user in a proxy setup */
/* we use the domain name as the module name to be loaded */
g_strncpy(section_name,
self->session->client_info->domain, 255);
} else
{ /* if no domain is given, and autorun is not specified in xrdp.ini
* use default_section_name as section_name */
g_strncpy(section_name, default_section_name, 255);
}
list_clear(names);
/* if given section name doesn't match any sections configured
* in xrdp.ini, fallback to default_section_name */ if (file_read_section(fd, section_name, names, values) != 0)
{
LOG(LOG_LEVEL_INFO, "Module \"%s\" specified by %s from %s " "is not configured. Using \"%s\" instead.",
section_name,
self->session->client_info->username,
self->session->client_info->client_description,
default_section_name);
list_clear(names);
list_clear(values);
/* look for the required module in xrdp.ini, fetch its parameters */ if (file_read_section(fd, section_name, names, values) == 0)
{ for (index = 0; index < names->count; index++)
{
q = (constchar *)list_get_item(names, index);
r = (constchar *)list_get_item(values, index);
if (g_strncasecmp("password", q, 255) == 0)
{ /* if the password has been asked for by the module, use what the clientsays. ifthepasswordhasbeenmanuallysetintheconfig,usethat
instead of what the client says. */ if (g_strncmp("ask", r, 3) == 0)
{
r = self->session->client_info->password;
}
} elseif (g_strncasecmp("username", q, 255) == 0)
{ /* if the username has been asked for by the module, use what the clientsays. iftheusernamehasbeenmanuallysetintheconfig,usethat
instead of what the client says. */ if (g_strncmp("ask", r, 3) == 0)
{
r = self->session->client_info->username;
}
} elseif (g_strncasecmp("ip", q, 255) == 0)
{ /* if the ip has been asked for by the module, use what the clientsays(targetipshouldbein'domain'field,whenstartingwith"_") iftheiphasbeenmanuallysetintheconfig,usethat
instead of what the client says. */ if (g_strncmp("ask", r, 3) == 0)
{ if (self->session->client_info->domain[0] == '_')
{
g_strncpy(param, &self->session->client_info->domain[1], 255);
r = param;
}
}
} elseif (g_strncasecmp("port", q, 255) == 0)
{ if (g_strncmp("ask3389", r, 7) == 0)
{
r = "3389"; /* use default */
}
}
if (self->session->client_info->gfx && !self->mm->egfx_up)
{ /* gfx session but have not recieved caps advertise yet,
set flag so we will connect to backend later */
self->mm->gfx_delay_autologin = 1;
} else
{ /* *Skiptheloginboxandgostraighttotheconnectionphase
*/
xrdp_wm_set_login_state(self, WMLS_START_CONNECT);
}
} else
{ /* Hopefully, we never reach here. */
LOG(LOG_LEVEL_WARNING, "Control should never reach %s:%d", __FILE__, __LINE__);
}
list_delete(names);
list_delete(values);
g_file_close(fd);
} else
{
LOG(LOG_LEVEL_WARNING, "xrdp_wm_init: Could not read xrdp.ini file %s",
self->session->xrdp_ini);
}
} else
{
LOG(LOG_LEVEL_DEBUG, " xrdp_wm_init: no autologin / auto run detected, draw login window");
xrdp_login_wnd_create(self); /* clear screen */
xrdp_bitmap_invalidate(self->screen, 0);
xrdp_wm_set_focused(self, self->login_window);
xrdp_wm_set_login_state(self, WMLS_USER_PROMPT);
}
/*****************************************************************************/ /* returns the number for rects visible for an area relative to a drawable */ /* putting the rects in region */ int
xrdp_wm_get_vis_region(struct xrdp_wm *self, struct xrdp_bitmap *bitmap, int x, int y, int cx, int cy, struct xrdp_region *region, int clip_children)
{ int i; struct xrdp_bitmap *p; struct xrdp_rect a; struct xrdp_rect b;
/* area we are drawing */
MAKERECT(a, bitmap->left + x, bitmap->top + y, cx, cy);
p = bitmap->parent;
while (p != 0)
{
RECTOFFSET(a, p->left, p->top);
p = p->parent;
}
if (clip_children)
{ /* loop through all windows in z order */ for (i = 0; i < self->screen->child_list->count; i++)
{
p = (struct xrdp_bitmap *)list_get_item(self->screen->child_list, i);
if (p == bitmap || p == bitmap->parent)
{ return0;
}
/*****************************************************************************/ /* return the window at x, y on the screen */ staticstruct xrdp_bitmap *
xrdp_wm_at_pos(struct xrdp_bitmap *wnd, int x, int y, struct xrdp_bitmap **wnd1)
{ int i; struct xrdp_bitmap *p; struct xrdp_bitmap *q;
/* loop through all windows in z order */ for (i = 0; i < wnd->child_list->count; i++)
{
p = (struct xrdp_bitmap *)list_get_item(wnd->child_list, i);
if (x >= p->left && y >= p->top && x < p->left + p->width &&
y < p->top + p->height)
{ if (wnd1 != 0)
{
*wnd1 = p;
}
q = xrdp_wm_at_pos(p, x - p->left, y - p->top, 0);
if (q == 0)
{ return p;
} else
{ return q;
}
}
}
return0;
}
/*****************************************************************************/ staticint
xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy)
{
self->painter->clip_children = 0;
self->painter->rop = 0x5a;
xrdp_painter_begin_update(self->painter);
self->painter->use_clip = 0;
self->painter->mix_mode = 1;
self->painter->brush.pattern[0] = 0xaa;
self->painter->brush.pattern[1] = 0x55;
self->painter->brush.pattern[2] = 0xaa;
self->painter->brush.pattern[3] = 0x55;
self->painter->brush.pattern[4] = 0xaa;
self->painter->brush.pattern[5] = 0x55;
self->painter->brush.pattern[6] = 0xaa;
self->painter->brush.pattern[7] = 0x55;
self->painter->brush.x_origin = 0;
self->painter->brush.y_origin = 0;
self->painter->brush.style = 3;
self->painter->bg_color = self->black;
self->painter->fg_color = self->white; /* top */
xrdp_painter_fill_rect(self->painter, self->screen, x, y, cx, 5); /* bottom */
xrdp_painter_fill_rect(self->painter, self->screen, x, y + (cy - 5), cx, 5); /* left */
xrdp_painter_fill_rect(self->painter, self->screen, x, y + 5, 5, cy - 10); /* right */
xrdp_painter_fill_rect(self->painter, self->screen, x + (cx - 5), y + 5, 5,
cy - 10);
xrdp_painter_end_update(self->painter);
self->painter->rop = 0xcc;
self->painter->clip_children = 1;
self->painter->mix_mode = 0; return0;
}
/*****************************************************************************/ /* return true if rect is totally exposed going in reverse z order */ /* from wnd up */ staticint
xrdp_wm_is_rect_vis(struct xrdp_wm *self, struct xrdp_bitmap *wnd, struct xrdp_rect *rect)
{ struct xrdp_rect wnd_rect; struct xrdp_bitmap *b; int i;;
/* if rect is part off screen */ if (rect->left < 0)
{ return0;
}
if (rect->top < 0)
{ return0;
}
if (rect->right >= self->screen->width)
{ return0;
}
if (rect->bottom >= self->screen->height)
{ return0;
}
i = list_index_of(self->screen->child_list, (long)wnd);
i--;
while (i >= 0)
{
b = (struct xrdp_bitmap *)list_get_item(self->screen->child_list, i);
MAKERECT(wnd_rect, b->left, b->top, b->width, b->height);
if (rect_intersect(rect, &wnd_rect, 0))
{ return0;
}
i--;
}
return1;
}
/*****************************************************************************/ staticint
xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd, int dx, int dy)
{ struct xrdp_rect rect1; struct xrdp_rect rect2; struct xrdp_region *r; int i;
/*****************************************************************************/ staticint
xrdp_wm_undraw_dragging_box(struct xrdp_wm *self, int do_begin_end)
{ int boxx; int boxy;
if (self == 0)
{ return0;
}
if (self->dragging)
{ if (self->draggingxorstate)
{ if (do_begin_end)
{
xrdp_painter_begin_update(self->painter);
}
if (do_begin_end)
{
xrdp_painter_end_update(self->painter);
}
}
}
return0;
}
/*****************************************************************************/ staticint
xrdp_wm_draw_dragging_box(struct xrdp_wm *self, int do_begin_end)
{ int boxx; int boxy;
if (self == 0)
{ return0;
}
if (self->dragging)
{ if (!self->draggingxorstate)
{ if (do_begin_end)
{
xrdp_painter_begin_update(self->painter);
}
if (do_begin_end)
{
xrdp_painter_end_update(self->painter);
}
}
}
return0;
}
/*****************************************************************************/ int
xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y)
{ struct xrdp_bitmap *b;
if (self == 0)
{ return0;
}
if (x < 0)
{
x = 0;
}
if (y < 0)
{
y = 0;
}
if (x >= self->screen->width)
{
x = self->screen->width;
}
if (y >= self->screen->height)
{
y = self->screen->height;
}
if (b == 0) /* if b is null, the movement must be over the screen */
{ if (self->screen->pointer != self->current_pointer)
{
xrdp_wm_set_pointer(self, self->screen->pointer);
self->current_pointer = self->screen->pointer;
}
if (self->mm->mod != 0) /* if screen is mod controlled */
{ if (self->mm->mod->mod_event != 0)
{
self->mm->mod->mod_event(self->mm->mod, WM_MOUSEMOVE, x, y, 0, 0);
}
}
}
/*****************************************************************************/ int
xrdp_wm_mouse_touch(struct xrdp_wm *self, int gesture, int param)
{
LOG(LOG_LEVEL_DEBUG, "mouse touch event gesture %d param %d", gesture, param);
switch (gesture)
{ case TOUCH_TWO_FINGERS_UP: case TOUCH_TWO_FINGERS_DOWN:
self->mm->mod->mod_event(self->mm->mod, WM_TOUCH_VSCROLL,
self->mouse_x, self->mouse_y, param, 0); break; case TOUCH_TWO_FINGERS_RIGHT: case TOUCH_TWO_FINGERS_LEFT:
self->mm->mod->mod_event(self->mm->mod, WM_TOUCH_HSCROLL,
self->mouse_x, self->mouse_y, param, 0); break;
}
return0;
}
/*****************************************************************************/ int
xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down)
{ struct xrdp_bitmap *control; struct xrdp_bitmap *focus_out_control; struct xrdp_bitmap *wnd; int newx; int newy; int oldx; int oldy;
if (self == 0)
{ return0;
}
if (x < 0)
{
x = 0;
}
if (y < 0)
{
y = 0;
}
if (x >= self->screen->width)
{
x = self->screen->width;
}
if (y >= self->screen->height)
{
y = self->screen->height;
}
if ((control->type == WND_TYPE_BUTTON ||
control->type == WND_TYPE_COMBO) &&
but == 1 && !down && self->button_down == control)
{ /* if clicking up on a button that was clicked down */
self->button_down = 0;
control->state = 0;
xrdp_bitmap_invalidate(control, 0);
if (control->parent != 0)
{ if (control->parent->notify != 0)
{ /* control can be invalid after this */
control->parent->notify(control->owner, control, 1, x, y);
}
}
} elseif ((control->type == WND_TYPE_BUTTON ||
control->type == WND_TYPE_COMBO) &&
but == 1 && down)
{ /* if clicking down on a button or combo */
self->button_down = control;
control->state = 1;
xrdp_bitmap_invalidate(control, 0);
/* no matter what, mouse is up, reset button_down */ if (but == 1 && !down && self->button_down != 0)
{
self->button_down = 0;
}
return0;
}
/*****************************************************************************/ int
xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code)
{ int msg; struct xrdp_key_info *ki;
/*****************************************************************************/ /* happens when client gets focus and sends key modifier info */ int
xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags)
{
self->num_lock = 0;
self->scroll_lock = 0;
self->caps_lock = 0;
if (key_flags & 1)
{
self->scroll_lock = 1;
}
if (key_flags & 2)
{
self->num_lock = 1;
}
if (key_flags & 4)
{
self->caps_lock = 1;
}
if (self->mm->mod != 0)
{ if (self->mm->mod->mod_event != 0)
{
self->mm->mod->mod_event(self->mm->mod, WM_KEYBRD_SYNC, key_flags,
device_flags, key_flags, device_flags);
}
}
return0;
}
/*****************************************************************************/ staticint
xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t unicode)
{ int index;
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{ if (unicode == self->keymap.keys_noshift[index].chr)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); return0;
}
}
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{ if (unicode == self->keymap.keys_shift[index].chr)
{ if (device_flags & KBD_FLAG_UP)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
} else
{
xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT);
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
} return0;
}
}
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{ if (unicode == self->keymap.keys_altgr[index].chr)
{ if (device_flags & KBD_FLAG_UP)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT,
XR_RDP_SCAN_ALT);
} else
{
xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
XR_RDP_SCAN_ALT);
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
} return0;
}
}
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{ if (unicode == self->keymap.keys_shiftaltgr[index].chr)
{ if (device_flags & KBD_FLAG_UP)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT, XR_RDP_SCAN_ALT);
xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
} else
{
xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT);
xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
XR_RDP_SCAN_ALT);
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
} return0;
}
}
return0;
}
/*****************************************************************************/ int
xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control)
{ int x; int y;
/*****************************************************************************/ staticint
xrdp_wm_process_input_mouse(struct xrdp_wm *self, int device_flags, int x, int y)
{
LOG_DEVEL(LOG_LEVEL_TRACE, "mouse event flags %4.4x x %d y %d", device_flags, x, y);
if (device_flags & PTRFLAGS_MOVE)
{
xrdp_wm_mouse_move(self, x, y);
}
if (device_flags & PTRFLAGS_BUTTON1)
{ if (device_flags & PTRFLAGS_DOWN)
{
xrdp_wm_mouse_click(self, x, y, 1, 1);
} else
{
xrdp_wm_mouse_click(self, x, y, 1, 0);
}
}
if (device_flags & PTRFLAGS_BUTTON2)
{ if (device_flags & PTRFLAGS_DOWN)
{
xrdp_wm_mouse_click(self, x, y, 2, 1);
} else
{
xrdp_wm_mouse_click(self, x, y, 2, 0);
}
}
if (device_flags & PTRFLAGS_BUTTON3)
{ if (device_flags & PTRFLAGS_DOWN)
{
xrdp_wm_mouse_click(self, x, y, 3, 1);
} else
{
xrdp_wm_mouse_click(self, x, y, 3, 0);
}
}
/******************************************************************************/ /* this is the callbacks coming from libxrdp.so */ int
callback(intptr_t id, int msg, intptr_t param1, intptr_t param2,
intptr_t param3, intptr_t param4)
{ int rv; struct xrdp_wm *wm; struct xrdp_rect rect;
if (id == 0) /* "id" should be "struct xrdp_process*" as long */
{ return0;
}
wm = ((struct xrdp_process *)id)->wm;
if (wm == 0)
{ return0;
}
rv = 0;
switch (msg)
{ case RDP_INPUT_SYNCHRONIZE:
rv = xrdp_wm_key_sync(wm, param3, param1); break; case RDP_INPUT_SCANCODE:
rv = xrdp_wm_key(wm, param3, param1); break; case RDP_INPUT_UNICODE:
rv = xrdp_wm_key_unicode(wm, param3, param1); break; case RDP_INPUT_MOUSE:
rv = xrdp_wm_process_input_mouse(wm, param3, param1, param2); break; case RDP_INPUT_MOUSEX:
rv = xrdp_wm_process_input_mousex(wm, param3, param1, param2); break; case0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */ /* like the rest, it's from RDP_PDU_DATA with code 33 */ /* it's the rdp client asking for a screen update */
MAKERECT(rect, param1, param2, param3, param4);
rv = xrdp_bitmap_invalidate(wm->screen, &rect); break; case0x5555: /* called from xrdp_channel.c, channel data has come in,
pass it to module if there is one */
rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4); break; case0x5556:
rv = xrdp_mm_check_chan(wm->mm); break; case0x5557:
LOG(LOG_LEVEL_TRACE, "callback: frame ack %p", (void *) param1);
xrdp_mm_frame_ack(wm->mm, param1); break; case0x5558:
xrdp_mm_drdynvc_up(wm->mm); break; case0x5559:
xrdp_mm_suppress_output(wm->mm, param1,
LOWORD(param2), HIWORD(param2),
LOWORD(param3), HIWORD(param3)); break; case0x555a: // "yeah, up_and_running"
xrdp_mm_up_and_running(wm->mm); break;
} return rv;
}
/******************************************************************************/ /* returns error */ /* this gets called when there is nothing on any socket */ staticint
xrdp_wm_login_state_changed(struct xrdp_wm *self)
{ if (self == 0)
{ return0;
}
LOG(LOG_LEVEL_DEBUG, "Login state has changed to %s",
xrdp_wm_login_state_to_str(self->login_state)); if (self->login_state == WMLS_RESET)
{
list_clear(self->log);
xrdp_wm_delete_all_children(self);
self->dragging = 0;
if (self->fatal_error_in_log_window)
{ /* We've got here after OK is pressed in the log
* window, so the user has read the message(s) in it */
g_set_wait_obj(self->pro_layer->self_term_event);
} else
{ /* this is the initial state of the login window */
xrdp_wm_set_login_state(self, WMLS_USER_PROMPT);
xrdp_wm_init(self);
}
} elseif (self->login_state == WMLS_START_CONNECT)
{
xrdp_wm_delete_all_children(self);
self->dragging = 0;
xrdp_wm_set_login_state(self, WMLS_CONNECT_IN_PROGRESS);
/* This calls back to xrdp_wm_mod_connect_done() when the
* connect is finished*/
xrdp_mm_connect(self->mm);
} elseif (self->login_state == WMLS_CLEANUP)
{
xrdp_wm_delete_all_children(self);
self->dragging = 0;
xrdp_wm_set_login_state(self, WMLS_INACTIVE);
}
return0;
}
/******************************************************************************/ /* this gets called when the module manager finishes a connect *whichwasinitiatedbyxrdp_mm_connect()
*/ void
xrdp_wm_mod_connect_done(struct xrdp_wm *self, int status)
{
LOG(LOG_LEVEL_DEBUG, "status from xrdp_mm_connect() : %d", status); if (status == 0)
{
xrdp_wm_set_login_state(self, WMLS_CLEANUP);
self->dragging = 0;
} else
{
xrdp_wm_set_login_state(self, WMLS_INACTIVE);
xrdp_wm_show_log(self);
}
}
/*****************************************************************************/ /* this is the log windows notify function */ staticint
xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd, struct xrdp_bitmap *sender, int msg, long param1, long param2)
{ struct xrdp_painter *painter; struct xrdp_wm *wm; struct xrdp_rect rect; int index; char *text;
if (wnd == 0)
{ return0;
}
if (sender == 0)
{ return0;
}
if (wnd->owner == 0)
{ return0;
}
wm = wnd->wm;
if (msg == 1) /* click */
{ if (sender->id == 1) /* ok button */
{ /* close the log window */
MAKERECT(rect, wnd->left, wnd->top, wnd->width, wnd->height);
xrdp_bitmap_delete(wnd);
xrdp_bitmap_invalidate(wm->screen, &rect);
/* if module is gone, reset the session when ok is clicked */ if (wm->mm->mod_handle == 0)
{ /* make sure autologin is off */
wm->session->client_info->rdp_autologin = 0;
xrdp_wm_set_login_state(wm, WMLS_RESET); /* reset session */
}
}
} elseif (msg == WM_PAINT) /* 3 */
{
painter = (struct xrdp_painter *)param1;
/*****************************************************************************/ int
xrdp_wm_show_log(struct xrdp_wm *self)
{ struct xrdp_bitmap *but; int w; int h; int xoffset; int yoffset;
uint32_t index; int primary_x_offset; int primary_y_offset;
if (self->hide_log_window)
{ /* make sure autologin is off */
self->session->client_info->rdp_autologin = 0;
xrdp_wm_set_login_state(self, WMLS_RESET); /* reset session */ return0;
}
if (self->log_wnd == 0)
{
w = self->xrdp_config->cfg_globals.ls_scaled.log_wnd_width;
h = self->xrdp_config->cfg_globals.ls_scaled.log_wnd_height;
xoffset = 10;
yoffset = 10;
if (self->screen->width < w)
{
w = self->screen->width - 4;
xoffset = 2;
}
if (self->screen->height < h)
{
h = self->screen->height - 4;
yoffset = 2;
}
primary_x_offset = 0;
primary_y_offset = 0;
/* multimon scenario, draw log window on primary monitor */ if (self->client_info->display_sizes.monitorCount > 1)
{ for (index = 0; index < self->client_info->display_sizes.monitorCount; index++)
{ if (self->client_info->display_sizes.minfo_wm[index].is_primary)
{
primary_x_offset = self->client_info->display_sizes.minfo_wm[index].left;
primary_y_offset = self->client_info->display_sizes.minfo_wm[index].top; break;
}
}
}
/*****************************************************************************/ int
xrdp_wm_get_wait_objs(struct xrdp_wm *self, tbus *robjs, int *rc,
tbus *wobjs, int *wc, int *timeout)
{ int i;
/******************************************************************************/ int
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
{ int rv;
if (self == 0)
{ return0;
}
rv = 0;
if (g_is_wait_obj_set(self->login_state_event))
{
g_reset_wait_obj(self->login_state_event);
xrdp_wm_login_state_changed(self);
}
if (rv == 0)
{
rv = xrdp_mm_check_wait_objs(self->mm);
}
return rv;
}
/*****************************************************************************/ constchar *
xrdp_wm_login_state_to_str(enum wm_login_state login_state)
{ constchar *result = "unknown"; /* Use a switch for this, as some compilers will warn about missing states
*/ switch (login_state)
{ case WMLS_RESET:
result = "WMLS_RESET"; break; case WMLS_USER_PROMPT:
result = "WMLS_USER_PROMPT"; break; case WMLS_START_CONNECT:
result = "WMLS_START_CONNECT"; break; case WMLS_CONNECT_IN_PROGRESS:
result = "WMLS_CONNECT_IN_PROGRESS"; break; case WMLS_CLEANUP:
result = "WMLS_CLEANUP"; break; case WMLS_INACTIVE:
result = "WMLS_INACTIVE";
}
return result;
}
/*****************************************************************************/ int
xrdp_wm_set_login_state(struct xrdp_wm *self, enum wm_login_state login_state)
{
LOG(LOG_LEVEL_DEBUG, "Login state change request %s -> %s",
xrdp_wm_login_state_to_str(self->login_state),
xrdp_wm_login_state_to_str(login_state));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.