// FreeRDP defines some macros that we have different values for. // To catch this we need to include the freerdp includes before our // local ones (see gcc bug #16358) #undef WM_LBUTTONUP #undef WM_LBUTTONDOWN #undef WM_RBUTTONUP #undef WM_RBUTTONDOWN
/*****************************************************************************/ /* return error */ staticint
lxrdp_start(struct mod *mod, int w, int h, int bpp)
{
rdpSettings *settings;
if (mod->allow_client_kbd_settings)
{
settings->kbd_type = mod->client_info.keyboard_type;
settings->kbd_subtype = mod->client_info.keyboard_subtype; /* Define the most common number of function keys, 12.
because we can't get it from client. */
settings->kbd_fn_keys = 12;
settings->kbd_layout = mod->client_info.keylayout;
/* Exception processing for each RDP Keyboard type */ if (mod->client_info.keyboard_type == 0x00)
{ /* 0x00000000 : Set on Server */
LOG(LOG_LEVEL_WARNING, "keyboard_type:[0x%02x] ,Set on Server",
mod->client_info.keyboard_type);
} elseif (mod->client_info.keyboard_type == 0x04)
{ /* 0x00000004 : IBM enhanced (101- or 102-key) keyboard */ /* Nothing to do. */
} elseif (mod->client_info.keyboard_type == 0x07)
{ /* 0x00000007 : Japanese keyboard */ /* Nothing to do. */
}
}
if (ko->type != 0)
{
LOG(LOG_LEVEL_INFO, "overrode kbd_type 0x%02X with 0x%02X",
settings->kbd_type, ko->type);
settings->kbd_type = ko->type;
}
if (ko->subtype != 0)
{
LOG(LOG_LEVEL_INFO, "overrode kbd_subtype 0x%02X with 0x%02X",
settings->kbd_subtype, ko->subtype);
settings->kbd_subtype = ko->subtype;
}
if (ko->fn_keys != 0)
{
LOG(LOG_LEVEL_INFO, "overrode kbd_fn_keys %d with %d",
settings->kbd_fn_keys, ko->fn_keys);
settings->kbd_fn_keys = ko->fn_keys;
}
if (ko->layout != 0)
{
LOG(LOG_LEVEL_INFO, "overrode kbd_layout 0x%08X with 0x%08X",
settings->kbd_layout, ko->layout);
settings->kbd_layout = ko->layout;
}
if (ko->layout_mask != 0)
{
LOG(LOG_LEVEL_INFO, "Masked kbd_layout 0x%08X to 0x%08X",
settings->kbd_layout, settings->kbd_layout & ko->layout_mask);
settings->kbd_layout &= ko->layout_mask;
}
LOG(LOG_LEVEL_INFO, buf);
mod->server_msg(mod, buf, 0);
} #else
{ /* This version of freerdp returns no useful information at
* all */
mod->server_msg(mod, "Neutrinordp connect failed.", 0);
mod->server_msg(mod, "No more information is available", 0);
mod->server_msg(mod, "Check host is up" " and credentials are correct", 0);
} #endif
LOG(LOG_LEVEL_ERROR, "NeutrinoRDP proxy connection: status [Failed]," " RDP client [%s], RDP server [%s:%d], RDP server username [%s]," " xrdp pamusername [%s], xrdp process id [%d]",
mod->client_info.client_description,
mod->inst->settings->hostname,
mod->inst->settings->port,
mod->inst->settings->username,
mod->pamusername,
g_getpid()); return1;
} else
{
LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Success]," " RDP client [%s], RDP server [%s:%d], RDP server username [%s]," " xrdp pamusername [%s], xrdp process id [%d]",
mod->client_info.client_description,
mod->inst->settings->hostname,
mod->inst->settings->port,
mod->inst->settings->username,
mod->pamusername,
g_getpid());
}
return0;
}
/******************************************************************************/ /* return error */ staticint
lxrdp_event(struct mod *mod, int msg, long param1, long param2, long param3, long param4)
{ int x; int y; int cx; int cy; int flags; int size; int total_size; int chanid; int lchid; char *data;
/* Before we handle the first character we synchronize
capslock and numlock. */ /* We collect the state during the first synchronize
( see msg 17) */ if (!mod->bool_keyBoardSynced)
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "Additional Sync event handled : %d", mod->keyBoardLockInfo);
mod->inst->input->SynchronizeEvent(mod->inst->input, mod->keyBoardLockInfo);
mod->bool_keyBoardSynced = 1;
}
case WM_KEYUP:
mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3); break;
case WM_KEYBRD_SYNC:
LOG_DEVEL(LOG_LEVEL_DEBUG, "Synchronized event handled : %ld", param1); /* In some situations the Synchronize event come to early. Thereforewestorethisinformationanduseitwhenwe receivethefirstkeyboardevent Withoutthisfixnumlockandcapslockcancome
out of sync. */
mod->inst->input->SynchronizeEvent(mod->inst->input, param1);
if (!mod->bool_keyBoardSynced)
{
mod->keyBoardLockInfo = param1;
}
break;
case WM_MOUSEMOVE: /* mouse move */
LOG_DEVEL(LOG_LEVEL_DEBUG, "mouse move %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_FLAGS_MOVE;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); break;
case WM_LBUTTONUP:
LOG_DEVEL(LOG_LEVEL_DEBUG, "left button up %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); break;
case WM_LBUTTONDOWN:
LOG_DEVEL(LOG_LEVEL_DEBUG, "left button down %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); break;
case WM_RBUTTONUP:
LOG_DEVEL(LOG_LEVEL_DEBUG, "right button up %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); break;
case WM_RBUTTONDOWN:
LOG_DEVEL(LOG_LEVEL_DEBUG, "right button down %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); break;
case WM_BUTTON3UP: /* middle button up */
LOG_DEVEL(LOG_LEVEL_DEBUG, "middle button up %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); break;
case WM_BUTTON3DOWN: /* middle button down */
LOG_DEVEL(LOG_LEVEL_DEBUG, "middle button down %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); break;
case WM_BUTTON4UP: /* wheel up */
flags = PTR_FLAGS_WHEEL | 0x0078;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); break;
case WM_BUTTON4DOWN: break;
case WM_BUTTON5UP: /* wheel down */
flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); break;
case WM_BUTTON5DOWN: break;
case WM_BUTTON8UP:
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button8 up %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_XFLAGS_BUTTON1;
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y); break;
case WM_BUTTON8DOWN:
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button8 down %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_DOWN;
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y); break;
case WM_BUTTON9UP:
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button9 up %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_XFLAGS_BUTTON2;
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y); break;
case WM_BUTTON9DOWN:
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button9 down %ld %ld", param1, param2);
x = param1;
y = param2;
flags = PTR_XFLAGS_BUTTON2 | PTR_XFLAGS_DOWN;
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y); break;
case WM_INVALIDATE:
LOG_DEVEL(LOG_LEVEL_DEBUG, "Invalidate request sent from client");
x = (param1 >> 16) & 0xffff;
y = (param1 >> 0) & 0xffff;
cx = (param2 >> 16) & 0xffff;
cy = (param2 >> 0) & 0xffff;
mod->inst->SendInvalidate(mod->inst, -1, x, y, cx, cy); break;
case WM_CHANNEL_DATA:
chanid = LOWORD(param1);
flags = HIWORD(param1);
size = (int)param2;
data = (char *)param3;
total_size = (int)param4;
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_event: client to server ,chanid= %d flags= %d", chanid, flags);
/******************************************************************************/ /* return error */ staticint
lxrdp_end(struct mod *mod)
{ int i; int j;
for (j = 0; j < 4; j++)
{ for (i = 0; i < 4096; i++)
{
g_free(mod->bitmap_cache[j][i].data);
}
}
for (i = 0; i < 64; i++)
{ if (mod->brush_cache[i].data != mod->brush_cache[i].b8x8)
{
g_free(mod->brush_cache[i].data);
}
}
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_end:");
LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Disconnect]," " RDP client [%s], RDP server [%s:%d], RDP server username [%s]," " xrdp pamusername [%s], xrdp process id [%d]",
mod->client_info.client_description,
mod->inst->settings->hostname,
mod->inst->settings->port,
mod->inst->settings->username,
mod->pamusername,
g_getpid()); return0;
}
/******************************************************************************/ staticint
lxrdp_session_change(struct mod *mod, int a, int b)
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_session_change: - no code here"); return0;
}
/******************************************************************************/ staticint
lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
tbus *write_objs, int *wcount, int *timeout)
{ void **rfds; void **wfds;
boolean ok;
if (!ok)
{
LOG(LOG_LEVEL_ERROR, "lxrdp_get_wait_objs: freerdp_get_fds failed"); return1;
}
}
return0;
}
/******************************************************************************/ staticint
lxrdp_check_wait_objs(struct mod *mod)
{
boolean ok;
LOG_DEVEL(LOG_LEVEL_TRACE, "lxrdp_check_wait_objs:"); /* *Onlyprocessthefreerdpfiledescriptorsifourqueuedoutputdata *hasnotreachedthelimit
*/ if (get_queued_module_output_data(mod) <= MAX_QUEUED_MODULE_OUTPUT_DATA)
{ /* *Beforecheckingthefiledescriptors,setthesourceinfo *currentsource,soanydataqueuedonoutputtransobjects *getsattributedtothismodule
*/ if (mod->si)
{
mod->si->cur_source = XRDP_SOURCE_MOD;
}
ok = freerdp_check_fds(mod->inst); if (mod->si)
{
mod->si->cur_source = XRDP_SOURCE_NONE;
}
if (!ok)
{
LOG(LOG_LEVEL_ERROR, "lxrdp_check_wait_objs: freerdp_check_fds failed"); return1;
}
}
return0;
}
/******************************************************************************/ staticint
lxrdp_frame_ack(struct mod *mod, int flags, int frame_id)
{ return0;
}
/******************************************************************************/ staticint
lxrdp_suppress_output(struct mod *mod, int suppress, int left, int top, int right, int bottom)
{ #ifdefined(NEUTRINORDP_HAS_SUPPRESS_OUTPUT)
mod->inst->SendSuppressOutput(mod->inst, !suppress, left, top, right, bottom); #endif return0;
}
/******************************************************************************/ staticint
lxrdp_server_version_message(struct mod *mod)
{ return0;
}
/******************************************************************************/ staticint
lxrdp_server_monitor_resize(struct mod *mod, int width, int height, int num_monitors, conststruct monitor_info *monitors, int *in_progress)
{
*in_progress = 0; return0;
}
/******************************************************************************/ staticint
lxrdp_server_monitor_full_invalidate(struct mod *mod, int width, int height)
{ return0;
}
/******************************************************************************/ staticvoid
lfreerdp_begin_paint(rdpContext *context)
{ struct mod *mod;
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_begin_paint:");
mod = ((struct mod_context *)context)->modi;
mod->server_begin_update(mod);
}
/******************************************************************************/ staticvoid
lfreerdp_end_paint(rdpContext *context)
{ struct mod *mod;
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_end_paint:");
mod = ((struct mod_context *)context)->modi;
mod->server_end_update(mod);
}
/******************************************************************************/ staticvoid
lfreerdp_set_bounds(rdpContext *context, rdpBounds *bounds)
{ struct mod *mod; int x; int y; int cx; int cy;
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_set_bounds: %p", bounds);
mod = ((struct mod_context *)context)->modi;
if (bounds != 0)
{
x = bounds->left;
y = bounds->top;
cx = (bounds->right - bounds->left) + 1;
cy = (bounds->bottom - bounds->top) + 1;
mod->server_set_clip(mod, x, y, cx, cy);
} else
{
mod->server_reset_clip(mod);
}
}
/******************************************************************************/ staticvoid
lfreerdp_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap)
{ struct mod *mod; int index; int cx; int cy; int server_bpp; int server_Bpp; int client_bpp; int j; int line_bytes;
BITMAP_DATA *bd; char *dst_data; char *dst_data1; char *src; char *dst;
/******************************************************************************/ staticvoid
lfreerdp_pat_blt(rdpContext *context, PATBLT_ORDER *patblt)
{ struct mod *mod; int idx; int fgcolor; int bgcolor; int server_bpp; int client_bpp; struct brush_item *bi;
mod = ((struct mod_context *)context)->modi;
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_pat_blt:");
/******************************************************************************/ staticvoid
lfreerdp_opaque_rect(rdpContext *context, OPAQUE_RECT_ORDER *opaque_rect)
{ struct mod *mod; int server_bpp; int client_bpp; int fgcolor;
/******************************************************************************/ staticvoid
lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
{ struct mod *mod; int server_bpp; int client_bpp; int fgcolor; int bgcolor; int opLeft; int opTop; int opRight; int opBottom;
/******************************************************************************/ staticvoid
lfreerdp_line_to(rdpContext *context, LINE_TO_ORDER *line_to)
{ struct mod *mod; int server_bpp; int client_bpp; int fgcolor; int bgcolor;
/******************************************************************************/ staticvoid
lfreerdp_cache_bitmapV2(rdpContext *context,
CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order)
{ char *dst_data; char *dst_data1; int bytes; int width; int height; int id; int idx; int flags; int server_bpp; int server_Bpp; int client_bpp; struct mod *mod;
/******************************************************************************/ staticvoid
lfreerdp_cache_brush(rdpContext *context, CACHE_BRUSH_ORDER *cache_brush_order)
{ int idx; int bytes; int bpp; int cx; int cy; struct mod *mod;
/******************************************************************************/ staticvoid
lfreerdp_pointer_system(rdpContext *context,
POINTER_SYSTEM_UPDATE *pointer_system)
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_system: - no code here type value = %d", pointer_system->type);
}
/******************************************************************************/ staticint
lfreerdp_get_pixel(void *bits, int width, int height, int bpp, int delta, int x, int y)
{ int start; int shift; int pixel;
tui8 *src8;
/******************************************************************************/ staticint
lfreerdp_set_pixel(int pixel, void *bits, int width, int height, int bpp, int delta, int x, int y)
{
tui8 *dst8; int start; int shift;
if (bpp == 1)
{
dst8 = (tui8 *)bits;
start = (y * delta) + x / 8;
shift = x % 8;
/******************************************************************************/ staticint
lfreerdp_convert_color_image(void *dst, int dst_width, int dst_height, int dst_bpp, int dst_delta, void *src, int src_width, int src_height, int src_bpp, int src_delta)
{ int i; int j; int pixel;
for (j = 0; j < dst_height; j++)
{ for (i = 0; i < dst_width; i++)
{
pixel = lfreerdp_get_pixel(src, src_width, src_height, src_bpp,
src_delta, i, j);
lfreerdp_set_pixel(pixel, dst, dst_width, dst_height, dst_bpp,
dst_delta, i, j);
}
}
return0;
}
/******************************************************************************/ staticvoid
lfreerdp_pointer_new(rdpContext *context,
POINTER_NEW_UPDATE *pointer_new)
{ struct mod *mod; int index; int bytes_per_pixel; int bits_per_pixel;
tui8 *dst;
tui8 *src;
/******************************************************************************/ staticvoid
lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc)
{ struct mod *mod; int i; struct
{ short x, y;
} points[4]; int fgcolor; int server_bpp, client_bpp;
mod->server_set_opcode(mod, polygon_sc->bRop2);
mod->server_set_bgcolor(mod, 255);
mod->server_set_fgcolor(mod, fgcolor);
mod->server_set_pen(mod, 1, 1); // style, width // TODO replace with correct brush; this is a workaround // This workaround handles the text cursor in microsoft word.
mod->server_draw_line(mod, polygon_sc->xStart, polygon_sc->yStart, polygon_sc->xStart, polygon_sc->yStart + points[2].y); // mod->server_fill_rect(mod, points[0].x, points[0].y, // points[0].x-points[3].x, points[0].y-points[2].y); // mod->server_set_brush(mod,); // howto use this on our indata??
mod->server_set_opcode(mod, 0xcc);
} else
{
LOG(LOG_LEVEL_WARNING, "Not handled number of points in lfreerdp_polygon_sc");
}
}
/******************************************************************************/ staticvoid
lfreerdp_synchronize(rdpContext *context)
{ /* Uncomment these two lines when needed */ #if0 struct mod *mod;
mod = ((struct mod_context *)context)->modi; #endif
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_synchronize received - not handled");
}
struct mod *mod; int index; int error; int num_chans; int target_chan; int ch_flags; char ch_name[CHANNEL_NAME_LEN + 1]; constchar *ch_names[MAX_FREERDP_CHANNELS]; char *dst_ch_name;
LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_pre_connect:");
mod = ((struct mod_context *)(instance->context))->modi;
verifyColorMap(mod);
num_chans = mod->server_get_channel_count(mod); if (num_chans < 0)
{
LOG(LOG_LEVEL_ERROR, "lfreerdp_pre_connect: Can't get channel count");
num_chans = 0;
}
target_chan = 0; for (index = 0 ; index < num_chans; ++index)
{
error = mod->server_query_channel(mod, index, ch_name, &ch_flags); if (error == 0)
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pre_connect: " "got channel [%s], id [%d], flags [0x%8.8x]",
ch_name, index, ch_flags);
if (g_strcmp(ch_name, DRDYNVC_SVC_CHANNEL_NAME) == 0)
{ /* xrdp currently reserves dynamic channels for its
* exclusive use (e.g. for GFX support) */
LOG(LOG_LEVEL_INFO, "Channel '%s' not passed to module",
ch_name);
} elseif (target_chan < MAX_FREERDP_CHANNELS)
{
dst_ch_name = instance->settings->channels[target_chan].name;
ch_names[target_chan] = dst_ch_name;
g_memset(dst_ch_name, 0, CHANNEL_NAME_LEN + 1);
g_snprintf(dst_ch_name, CHANNEL_NAME_LEN + 1, "%s", ch_name);
instance->settings->channels[target_chan].options = ch_flags;
++target_chan;
}
}
}
instance->settings->glyph_cache = true; /* GLYPH_SUPPORT_FULL and GLYPH_SUPPORT_PARTIAL seem to be the same */ /* disabled as workaround for corrupted display like black bars left of cmd with W2K8 */ /* instance->settings->glyphSupportLevel = GLYPH_SUPPORT_FULL; */
instance->settings->glyphSupportLevel = GLYPH_SUPPORT_NONE;
if ((mod->username[0] != 0) && (mod->password[0] != 0))
{ /* since we have username and password, we can try nla */
instance->settings->nla_security = 1;
} else
{
instance->settings->nla_security = 0;
}
return1;
}
/*****************************************************************************/ void
lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
WINDOW_STATE_ORDER *window_state)
{ int index; struct mod *mod; struct rail_window_state_order wso;
UNICONV *uniconv;
LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowCreate:");
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context *)context)->modi;
memset(&wso, 0, sizeof(wso)); /* copy the window state order */
wso.owner_window_id = window_state->ownerWindowId;
wso.style = window_state->style;
wso.extended_style = window_state->extendedStyle;
wso.show_state = window_state->showState;
/******************************************************************************/ staticint
lfreerdp_receive_channel_data(freerdp *instance, int channelId, uint8 *data, int size, int flags, int total_size)
{ struct mod *mod; int lchid; int index; int error;
mod = ((struct mod_context *)(instance->context))->modi;
lchid = -1;
for (index = 0; index < instance->settings->num_channels; index++)
{ if (instance->settings->channels[index].channel_id == channelId)
{
lchid = index; break;
}
}
if (lchid >= 0)
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_receive_channel_data: server to client, chanid: %d", lchid);
error = mod->server_send_to_channel(mod, lchid, (char *)data, size,
total_size, flags);
if (error != 0)
{
LOG(LOG_LEVEL_ERROR, "lfreerdp_receive_channel_data: error %d", error);
}
} else
{
LOG(LOG_LEVEL_ERROR, "lfreerdp_receive_channel_data: bad lchid");
}
/******************************************************************************/ staticint
lfreerdp_session_info(freerdp *instance, uint8 *data, int data_bytes)
{ struct mod *mod; int error;
/******************************************************************************/ int EXPORT_CC
mod_exit(tintptr handle)
{ struct mod *mod = (struct mod *) handle;
LOG_DEVEL(LOG_LEVEL_TRACE, "mod_exit:");
if (mod == 0)
{ return0;
}
if (mod->inst == NULL)
{
LOG(LOG_LEVEL_ERROR, "mod_exit - null pointer for inst:");
g_free(mod); return0 ;
}
freerdp_disconnect(mod->inst);
if ((mod->vmaj == 1) && (mod->vmin == 0) && (mod->vrev == 1))
{ /* this version has a bug with double free in freerdp_free */
} else
{
freerdp_context_free(mod->inst);
}
freerdp_free(mod->inst);
g_free(mod); return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.35 Sekunden
(vorverarbeitet am 2026-07-10)
¤
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.