[EMAIL PROTECTED] wrote:
> Not yet! In fact, as I dig into the problem further, I get more confused
> and discouraged.

Whoa! Perhaps that's because we're trying to be greedy and get everything 
working at the same time.

Let's see if we can get a simple xforms dialog working first and then see if 
we can merge this into LyX. Try and use the attached, simple xforms code 
for your testing together with the attached patch to xforms' input.c

Of course, I don't know what I'm doing when it comes to the nitty gritty of 
creating an input context, but can't you create and then destroy a new one 
each time you toggle the input method? That's what my patch to input.c 
does. (Well, it doesn't destroy it, but that should be straightforward.)

Sure, it may be a relatively expensive way of doing things, but so what? 
Especially for now.

The code compiles and DOES NOT CRASH when I use it, so that's a start. I 
assume that you'll have to move the code in lyxim into the xforms library 
to actually proceed from here (input CJK) but that was the point of the 
excercise wasn't it?

-- 
Angus
--- input_orig.c	2003-01-27 19:05:56.000000000 +0000
+++ input.c	2003-01-28 17:22:03.000000000 +0000
@@ -107,6 +107,7 @@
     int dead_area, attrib;
     int no_cursor;
     int field_char;
+    int CJK_local_input;
 }
 SPEC;
 
@@ -815,6 +816,63 @@
     return ret;
 }
 
+static void turn_on_local_input(FL_OBJECT * ob)
+{
+    SPEC *sp = ob->spec;
+
+    printf("Turning on CJK local input\n");
+    sp->CJK_local_input = 1;
+
+    if (fl_context->xim) { 
+	XIMStyles *styles = 0;
+	XIMStyle xim_style = 0;
+	XIMStyle xim_preferred_style =  XIMPreeditPosition|XIMStatusNothing;
+	XGetIMValues(fl_context->xim, XNQueryInputStyle, &styles, (char *) 0, (char *) 0 );
+	if ( styles ) {
+	    int i;
+	    for ( i = 0; !xim_style && i < styles->count_styles; i++ ) {
+		if ( styles->supported_styles[i] == xim_preferred_style ) {
+		    xim_style = xim_preferred_style;
+		    break;
+		}
+	    }
+
+	    for ( i = 0; !xim_style && i < styles->count_styles; i++ ) {
+		if ( styles->supported_styles[i] == (XIMPreeditNothing |
+						     XIMStatusNothing) ) {
+		    xim_style = XIMPreeditNothing | XIMStatusNothing;
+		    break;
+		}
+	    }
+
+	    for ( i = 0; !xim_style && i < styles->count_styles; i++ ) {
+		if ( styles->supported_styles[i] == (XIMPreeditNone |
+						     XIMStatusNone) ) {
+		    xim_style = XIMPreeditNone | XIMStatusNone;
+		    break;
+		}
+	    }
+
+	    XFree( (char *)styles );
+        }
+	fl_context->xic = XCreateIC(fl_context->xim,
+				    XNInputStyle, xim_style,
+				    0);
+    }
+}
+
+
+static void turn_off_local_input(FL_OBJECT * ob)
+{
+    SPEC *sp = ob->spec;
+    printf("Turning off CJK local input\n");
+    sp->CJK_local_input = 0;
+
+    /* Reset fl_context->xic to 'normal'? */
+    
+}
+
+
 /* Handles a key press, returns whether something has changed */
 static int
 handle_key(FL_OBJECT * ob, int key, unsigned kmask)
@@ -878,7 +936,23 @@
     else if (key == kmap.moveto_prev_page)
 	key = XK_PageUp;
 
-    if (IsRegular(key))		/* Normal keys  or NL */
+    /* toggle input method for CJK users */
+    if (key == XK_space) {
+	int input_method_toggled=0;
+	if (shiftkey_down(kmask) && !sp->CJK_local_input) {
+	    input_method_toggled=1;
+	    turn_on_local_input(ob);
+	} else if (!shiftkey_down(kmask) && sp->CJK_local_input) {
+	    input_method_toggled=1;
+	    turn_off_local_input(ob);
+	}
+	/* If we have simply toggled the input method, then
+	   don't output the  XK_space */
+	if (input_method_toggled)
+	    return 0;
+    }
+
+    if (IsRegular(key))	/* Normal keys  or NL */
     {
 	int ok = FL_VALID;
 	char *tmpbuf = 0;
@@ -1352,6 +1426,7 @@
     sp->dummy->spec = sp;
     sp->input = ob;
     sp->field_char = ' ';
+    sp->CJK_local_input = 0;
 
     /* can't remember why validated input return is set to RETURN_END 
        but probably with some reason. Wait until 1.0 to reset it
// Compiles with
// g++ -W -o trial trial.C -L$HOME/xforms-1.0-release/lib -lforms-static \
//            -L/usr/X11R6/lib -lX11
#include <X11/forms.h>
#include <stdlib.h>
#include <iostream>

struct FD_test {
	FL_FORM   * form;
	FL_OBJECT * input_1;
	FL_OBJECT * input_2;
	FL_OBJECT * button_close;
};

extern "C" {

void InputCB(FL_OBJECT *, long);
void CloseCB(FL_OBJECT *, long);
int WMHideCB(FL_FORM * form, void *);
}

FD_test * build_form();

// globally accessible.
FD_test * dialog = 0;
bool finished=false;

int main(int argc, char *argv[]) 
{
	fl_initialize(&argc, argv, 0, 0, 0);

	dialog = build_form();
	fl_set_input_return(dialog->input_1, FL_RETURN_CHANGED);
	fl_set_input_return(dialog->input_2, FL_RETURN_CHANGED);
	fl_set_form_atclose(dialog->form, WMHideCB, 0);
	fl_show_form(dialog->form, FL_PLACE_MOUSE, FL_FULLBORDER, "trial");

	while (!finished)
		fl_check_forms();

	fl_free_form(dialog->form);
	delete dialog;
	return 0;
}

void finish() 
{
	if (dialog->form && dialog->form->visible)
		fl_hide_form(dialog->form);
	finished = true;
}

extern "C" {

void InputCB(FL_OBJECT * ob, long)
{
	char const * const cstr = fl_get_input(ob);
        std::cerr << ob->label << ": " << cstr << std::endl;
}

void CloseCB(FL_OBJECT *, long)
{
	finish();
}


int WMHideCB(FL_FORM * form, void *)
{
	finish();
        return FL_CANCEL;
}

} // extern "C"
 
FD_test * build_form()
{
	FL_OBJECT *obj;
	FD_test *fdui = new FD_test;

	fdui->form = fl_bgn_form(FL_NO_BOX, 300, 210);
	obj = fl_add_box(FL_UP_BOX,0,0,300,210,"");
	fdui->input_1 = obj = fl_add_input(FL_NORMAL_INPUT,50,10,240,30,"Input1");
	fl_set_object_lsize(obj,FL_NORMAL_SIZE);
	fl_set_object_callback(obj,InputCB,0);
	fdui->input_2 = obj = fl_add_input(FL_NORMAL_INPUT,50,70,240,30,"Input2");
	fl_set_object_lsize(obj,FL_NORMAL_SIZE);
	fl_set_object_callback(obj,InputCB,0);
	fdui->button_close = obj = fl_add_button(FL_NORMAL_BUTTON,210,170,80,30,"Close|^[");
	fl_set_object_lsize(obj,FL_NORMAL_SIZE);
	fl_set_object_callback(obj,CloseCB,0);
	fl_end_form();

	fdui->form->fdui = fdui;

	return fdui;
}

Reply via email to