Compare commits

..

60 Commits

Author SHA1 Message Date
blizzard%redhat.com
2ca39b9b17 merge from head
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53740 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-17 03:57:27 +00:00
blizzard%redhat.com
fe94a6ca17 merges from head
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53737 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-17 03:27:47 +00:00
blizzard%redhat.com
dbd81545d5 remove these files from the branch, they are elsewhere in head now...
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53733 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-17 03:14:54 +00:00
blizzard%redhat.com
eae64955ac merge modal changes from head
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53660 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 16:15:13 +00:00
blizzard%redhat.com
ac2b83c0f5 merge IM fixes from head
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53656 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 16:08:54 +00:00
blizzard%redhat.com
4de4b9b262 merges from head
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53653 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 15:56:04 +00:00
(no author)
585367a7b8 This commit was manufactured by cvs2svn to create branch 'SUPERWIN'.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53594 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-16 01:52:21 +00:00
blizzard%redhat.com
8226158ae4 focus changes from head
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53447 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-14 04:34:41 +00:00
blizzard%redhat.com
9cb5b0bd0f don't clear the xlate queue for ConfigureEvents on shell windows since the xlate queue has nothing to do with that shell window...
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53425 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-13 15:10:10 +00:00
blizzard%redhat.com
ac24bf46fe merges from head
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53408 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-13 04:55:21 +00:00
blizzard%redhat.com
feb3b49669 work around for lame NS_SIZE event problems...
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53361 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-12 20:24:19 +00:00
blizzard%redhat.com
e4d84ceca8 use the external gtksuperwin library
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53360 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-12 20:14:52 +00:00
blizzard%redhat.com
63e9105b5f add gtksuperwin to the build list
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53359 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-12 20:13:40 +00:00
blizzard%redhat.com
21904a64db patch from claudius@netscape.com to make this build on platforms with picky c++ compilers
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53355 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-12 18:10:02 +00:00
blizzard%redhat.com
6d8df6d4e7 add a -lgtksuperwin for the viewer since it embeds a native widget into the layout
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53354 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-12 17:29:47 +00:00
blizzard%redhat.com
8f49d292ca merge in some of pav's IM changes...
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53281 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-12 00:04:56 +00:00
pavlov%netscape.com
e1431cd937 fix loop in debugging code
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53251 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-11 22:03:47 +00:00
blizzard%redhat.com
d8ee1acce8 make sure that we do a gtk_style_attach() in the realize method so the style doesn't get destroyed early...
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53241 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-11 21:39:27 +00:00
blizzard%redhat.com
db224b8d6e merge in clipboard changes. remove some more debugging spew.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53089 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-10 21:29:44 +00:00
blizzard%redhat.com
37106d7fc3 remove more debugging spew
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53088 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-10 21:05:38 +00:00
blizzard%redhat.com
0c074d2a55 remove debugging spew
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53086 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-10 19:35:01 +00:00
blizzard%redhat.com
7d47d3aace make sure to send focus in and focus out events properly when giving focus to a superwin.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53085 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-10 19:31:50 +00:00
blizzard%redhat.com
4d1a2e8639 merge the license whackage
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53020 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 23:06:12 +00:00
blizzard%redhat.com
8b6d035f17 add focus support
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53016 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 22:53:26 +00:00
blizzard%redhat.com
4d22490af1 fix warnings due to passing bad data to the debug code
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@53008 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 19:48:03 +00:00
blizzard%redhat.com
4a1d8f7401 fix bogus warnings for gtk_signal_emit_stop_by_name
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52997 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 17:20:22 +00:00
blizzard%redhat.com
3ed82d86a0 add nsWindow::SetCursor
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52996 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 17:10:22 +00:00
blizzard%redhat.com
e763644046 fix background colors on windows
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52995 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-09 17:03:43 +00:00
blizzard%redhat.com
e94c0535d1 add hacks for superwin
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52971 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:56:27 +00:00
blizzard%redhat.com
201eebe4ec add mozbox code
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52965 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:34:41 +00:00
blizzard%redhat.com
91802fc4cb add superwin code for mozbox
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52964 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:34:22 +00:00
pavlov%netscape.com
68a592d45f fix debugging stuff like flashing, etc
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52963 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 22:32:36 +00:00
blizzard%redhat.com
60c89eba4b export our gtk header files. we'll need them for embedding.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52953 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 21:52:35 +00:00
blizzard%redhat.com
ceecd95095 make sure that the child window uses the same destroy as the nsWindow class
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52950 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 21:40:54 +00:00
blizzard%redhat.com
220151a643 assert if we get passed bad data. this is for testing.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52944 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-08 16:11:10 +00:00
blizzard%redhat.com
35d00c2c83 only send resize events on windows that are toplevel or have been created with a native parent
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52930 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-07 19:31:15 +00:00
blizzard%redhat.com
dfccc12330 add nsWindow::SetBackgroundColor, fix a warning
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52923 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 20:39:28 +00:00
(no author)
3c0a628da5 This commit was manufactured by cvs2svn to create branch 'SUPERWIN'.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52913 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 03:43:57 +00:00
blizzard%redhat.com
e67e916ea6 turn off the backing store for now
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52889 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 00:30:53 +00:00
blizzard%redhat.com
2312b5fc11 fix problems with using nsWindow::WidgetToScreen with toplevel windows
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52863 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 21:37:52 +00:00
blizzard%redhat.com
fcb064c579 turn on backing store for the bin_window
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52856 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 16:39:20 +00:00
blizzard%redhat.com
72255234ea add expose event compression
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52854 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 15:58:56 +00:00
blizzard%redhat.com
2cff6771cb never assign a mozarea to mMozArea unless you own it.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52853 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 15:49:31 +00:00
pavlov%netscape.com
f16eb3c3d2 fix WidgetToScreen
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52850 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 06:05:37 +00:00
pavlov%netscape.com
cc5f4699b6 remove #ifdef GTK_FIXED crap. make USE_SUPERWIN default, and fix native system color stuff (to be in head soon)
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52845 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-05 05:45:52 +00:00
blizzard%redhat.com
8dbfb05c9f fix some refcounting problems with the superwin and mozarea
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52821 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 23:12:20 +00:00
blizzard%redhat.com
4f6c078a40 make sure to destroy the superwin when the object goes out of scope
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52806 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 21:51:50 +00:00
blizzard%redhat.com
f303b7b880 add queued drawing
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52803 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 21:16:21 +00:00
blizzard%redhat.com
d5d532bbdf make rollup events work.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52801 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 20:33:34 +00:00
blizzard%redhat.com
1e9545d94e scrolling added
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52797 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 20:06:53 +00:00
blizzard%redhat.com
bbaf2a8966 implement nsWindow::Resize and nsWindow::Move methods
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52772 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-04 03:25:04 +00:00
blizzard%redhat.com
4979b2734e first pass at getting superwin code to build. it will run now but doesn't have nsWindow::Move and nsWindow::Resize implemented...
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52747 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-03 23:07:52 +00:00
blizzard%redhat.com
0ba4ab32b2 fix some indenting issues
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52724 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-03 20:10:28 +00:00
blizzard%redhat.com
53df453f1a add gdk event handler
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52722 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-03 19:47:14 +00:00
blizzard%redhat.com
db90d4ddcf start adding glue code for events for the superwin and mozbox code. also, add the box and superwin as class members.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52721 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-03 18:58:37 +00:00
blizzard%redhat.com
24a4aec113 change all of the debugging calls to use GtkObject or GtkWidget
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52718 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-03 16:38:21 +00:00
blizzard%redhat.com
74599c2956 change all of the CreateNative calls to use GtkObject instead of GtkWidget
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52717 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-03 16:09:35 +00:00
(no author)
9b52dc355f This commit was manufactured by cvs2svn to create branch 'SUPERWIN'.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52698 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-03 07:34:51 +00:00
blizzard%redhat.com
1792ff0e46 start on the branch to get the superwin code to build.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52591 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 22:21:47 +00:00
(no author)
fb08d16e05 This commit was manufactured by cvs2svn to create branch 'SUPERWIN'.
git-svn-id: svn://10.0.0.236/branches/SUPERWIN@52461 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 01:25:01 +00:00
93 changed files with 19303 additions and 12368 deletions

View File

@@ -1,539 +0,0 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the elliptic curve math library for binary polynomial
* field curves.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Douglas Stebila <douglas@stebila.ca>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifdef NSS_ENABLE_ECC
/*
* GF2m_ecl.c: Contains an implementation of elliptic curve math library
* for curves over GF2m.
*
* XXX Can be moved to a separate subdirectory later.
*
*/
#include "GF2m_ecl.h"
#include "mpi/mplogic.h"
#include "mpi/mp_gf2m.h"
#include <stdlib.h>
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
mp_err
GF2m_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py)
{
if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
return MP_YES;
} else {
return MP_NO;
}
}
/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
mp_err
GF2m_ec_pt_set_inf_aff(mp_int *px, mp_int *py)
{
mp_zero(px);
mp_zero(py);
return MP_OKAY;
}
/* Computes R = P + Q based on IEEE P1363 A.10.2.
* Elliptic curve points P, Q, and R can all be identical.
* Uses affine coordinates.
*/
mp_err
GF2m_ec_pt_add_aff(const mp_int *pp, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int lambda, xtemp, ytemp;
unsigned int *p;
int p_size;
p_size = mp_bpoly2arr(pp, p, 0) + 1;
p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size));
if (p == NULL) goto cleanup;
mp_bpoly2arr(pp, p, p_size);
CHECK_MPI_OK( mp_init(&lambda) );
CHECK_MPI_OK( mp_init(&xtemp) );
CHECK_MPI_OK( mp_init(&ytemp) );
/* if P = inf, then R = Q */
if (GF2m_ec_pt_is_inf_aff(px, py) == 0) {
CHECK_MPI_OK( mp_copy(qx, rx) );
CHECK_MPI_OK( mp_copy(qy, ry) );
err = MP_OKAY;
goto cleanup;
}
/* if Q = inf, then R = P */
if (GF2m_ec_pt_is_inf_aff(qx, qy) == 0) {
CHECK_MPI_OK( mp_copy(px, rx) );
CHECK_MPI_OK( mp_copy(py, ry) );
err = MP_OKAY;
goto cleanup;
}
/* if px != qx, then lambda = (py+qy) / (px+qx),
* xtemp = a + lambda^2 + lambda + px + qx
*/
if (mp_cmp(px, qx) != 0) {
CHECK_MPI_OK( mp_badd(py, qy, &ytemp) );
CHECK_MPI_OK( mp_badd(px, qx, &xtemp) );
CHECK_MPI_OK( mp_bdivmod(&ytemp, &xtemp, pp, p, &lambda) );
CHECK_MPI_OK( mp_bsqrmod(&lambda, p, &xtemp) );
CHECK_MPI_OK( mp_badd(&xtemp, &lambda, &xtemp) );
CHECK_MPI_OK( mp_badd(&xtemp, a, &xtemp) );
CHECK_MPI_OK( mp_badd(&xtemp, px, &xtemp) );
CHECK_MPI_OK( mp_badd(&xtemp, qx, &xtemp) );
} else {
/* if py != qy or qx = 0, then R = inf */
if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
}
/* lambda = qx + qy / qx */
CHECK_MPI_OK( mp_bdivmod(qy, qx, pp, p, &lambda) );
CHECK_MPI_OK( mp_badd(&lambda, qx, &lambda) );
/* xtemp = a + lambda^2 + lambda */
CHECK_MPI_OK( mp_bsqrmod(&lambda, p, &xtemp) );
CHECK_MPI_OK( mp_badd(&xtemp, &lambda, &xtemp) );
CHECK_MPI_OK( mp_badd(&xtemp, a, &xtemp) );
}
/* ry = (qx + xtemp) * lambda + xtemp + qy */
CHECK_MPI_OK( mp_badd(qx, &xtemp, &ytemp) );
CHECK_MPI_OK( mp_bmulmod(&ytemp, &lambda, p, &ytemp) );
CHECK_MPI_OK( mp_badd(&ytemp, &xtemp, &ytemp) );
CHECK_MPI_OK( mp_badd(&ytemp, qy, ry) );
/* rx = xtemp */
CHECK_MPI_OK( mp_copy(&xtemp, rx) );
cleanup:
mp_clear(&lambda);
mp_clear(&xtemp);
mp_clear(&ytemp);
free(p);
return err;
}
/* Computes R = P - Q.
* Elliptic curve points P, Q, and R can all be identical.
* Uses affine coordinates.
*/
mp_err
GF2m_ec_pt_sub_aff(const mp_int *pp, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int nqy;
MP_DIGITS(&nqy) = 0;
CHECK_MPI_OK( mp_init(&nqy) );
/* nqy = qx+qy */
CHECK_MPI_OK( mp_badd(qx, qy, &nqy) );
err = GF2m_ec_pt_add_aff(pp, a, px, py, qx, &nqy, rx, ry);
cleanup:
mp_clear(&nqy);
return err;
}
/* Computes R = 2P.
* Elliptic curve points P and R can be identical.
* Uses affine coordinates.
*/
mp_err
GF2m_ec_pt_dbl_aff(const mp_int *pp, const mp_int *a, const mp_int *px,
const mp_int *py, mp_int *rx, mp_int *ry)
{
return GF2m_ec_pt_add_aff(pp, a, px, py, px, py, rx, ry);
}
/* Gets the i'th bit in the binary representation of a.
* If i >= length(a), then return 0.
* (The above behaviour differs from mpl_get_bit, which
* causes an error if i >= length(a).)
*/
#define MP_GET_BIT(a, i) \
((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
/* Computes R = nP based on IEEE P1363 A.10.3.
* Elliptic curve points P and R can be identical.
* Uses affine coordinates.
*/
mp_err
GF2m_ec_pt_mul_aff(const mp_int *pp, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int k, k3, qx, qy, sx, sy;
int b1, b3, i, l;
unsigned int *p;
int p_size;
MP_DIGITS(&k) = 0;
MP_DIGITS(&k3) = 0;
MP_DIGITS(&qx) = 0;
MP_DIGITS(&qy) = 0;
MP_DIGITS(&sx) = 0;
MP_DIGITS(&sy) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&k3) );
CHECK_MPI_OK( mp_init(&qx) );
CHECK_MPI_OK( mp_init(&qy) );
CHECK_MPI_OK( mp_init(&sx) );
CHECK_MPI_OK( mp_init(&sy) );
p_size = mp_bpoly2arr(pp, p, 0) + 1;
p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size));
if (p == NULL) goto cleanup;
mp_bpoly2arr(pp, p, p_size);
/* if n = 0 then r = inf */
if (mp_cmp_z(n) == 0) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
}
/* Q = P, k = n */
CHECK_MPI_OK( mp_copy(px, &qx) );
CHECK_MPI_OK( mp_copy(py, &qy) );
CHECK_MPI_OK( mp_copy(n, &k) );
/* if n < 0 then Q = -Q, k = -k */
if (mp_cmp_z(n) < 0) {
CHECK_MPI_OK( mp_badd(&qx, &qy, &qy) );
CHECK_MPI_OK( mp_neg(&k, &k) );
}
#ifdef EC_DEBUG /* basic double and add method */
l = mpl_significant_bits(&k) - 1;
mp_zero(&sx);
mp_zero(&sy);
for (i = l; i >= 0; i--) {
/* if k_i = 1, then S = S + Q */
if (mpl_get_bit(&k, i) != 0) {
CHECK_MPI_OK( GF2m_ec_pt_add_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) );
}
if (i > 0) {
/* S = 2S */
CHECK_MPI_OK( GF2m_ec_pt_dbl_aff(pp, a, &sx, &sy, &sx, &sy) );
}
}
#else /* double and add/subtract method from standard */
/* k3 = 3 * k */
mp_set(&k3, 0x3);
CHECK_MPI_OK( mp_mul(&k, &k3, &k3) );
/* S = Q */
CHECK_MPI_OK( mp_copy(&qx, &sx) );
CHECK_MPI_OK( mp_copy(&qy, &sy) );
/* l = index of high order bit in binary representation of 3*k */
l = mpl_significant_bits(&k3) - 1;
/* for i = l-1 downto 1 */
for (i = l - 1; i >= 1; i--) {
/* S = 2S */
CHECK_MPI_OK( GF2m_ec_pt_dbl_aff(pp, a, &sx, &sy, &sx, &sy) );
b3 = MP_GET_BIT(&k3, i);
b1 = MP_GET_BIT(&k, i);
/* if k3_i = 1 and k_i = 0, then S = S + Q */
if ((b3 == 1) && (b1 == 0)) {
CHECK_MPI_OK( GF2m_ec_pt_add_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) );
/* if k3_i = 0 and k_i = 1, then S = S - Q */
} else if ((b3 == 0) && (b1 == 1)) {
CHECK_MPI_OK( GF2m_ec_pt_sub_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) );
}
}
#endif
/* output S */
CHECK_MPI_OK( mp_copy(&sx, rx) );
CHECK_MPI_OK( mp_copy(&sy, ry) );
cleanup:
mp_clear(&k);
mp_clear(&k3);
mp_clear(&qx);
mp_clear(&qy);
mp_clear(&sx);
mp_clear(&sy);
free(p);
return err;
}
/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
* coordinates.
* Uses algorithm Mdouble in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
* modified to not require precomputation of c=b^{2^{m-1}}.
*/
static mp_err
gf2m_Mdouble(const mp_int *pp, const unsigned int p[], const mp_int *a,
const mp_int *b, mp_int *x, mp_int *z)
{
mp_err err = MP_OKAY;
mp_int t1;
MP_DIGITS(&t1) = 0;
CHECK_MPI_OK( mp_init(&t1) );
CHECK_MPI_OK( mp_bsqrmod(x, p, x) );
CHECK_MPI_OK( mp_bsqrmod(z, p, &t1) );
CHECK_MPI_OK( mp_bmulmod(x, &t1, p, z) );
CHECK_MPI_OK( mp_bsqrmod(x, p, x) );
CHECK_MPI_OK( mp_bsqrmod(&t1, p, &t1) );
CHECK_MPI_OK( mp_bmulmod(b, &t1, p, &t1) );
CHECK_MPI_OK( mp_badd(x, &t1, x) );
cleanup:
mp_clear(&t1);
return err;
}
/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
* projective coordinates.
* Uses algorithm Madd in appendix of
* Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
*/
static mp_err
gf2m_Madd(const mp_int *pp, const unsigned int p[], const mp_int *a,
const mp_int *b, const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2,
mp_int *z2)
{
mp_err err = MP_OKAY;
mp_int t1, t2;
MP_DIGITS(&t1) = 0;
MP_DIGITS(&t2) = 0;
CHECK_MPI_OK( mp_init(&t1) );
CHECK_MPI_OK( mp_init(&t2) );
CHECK_MPI_OK( mp_copy(x, &t1) );
CHECK_MPI_OK( mp_bmulmod(x1, z2, p, x1) );
CHECK_MPI_OK( mp_bmulmod(z1, x2, p, z1) );
CHECK_MPI_OK( mp_bmulmod(x1, z1, p, &t2) );
CHECK_MPI_OK( mp_badd(z1, x1, z1) );
CHECK_MPI_OK( mp_bsqrmod(z1, p, z1) );
CHECK_MPI_OK( mp_bmulmod(z1, &t1, p, x1) );
CHECK_MPI_OK( mp_badd(x1, &t2, x1) );
cleanup:
mp_clear(&t1);
mp_clear(&t2);
return err;
}
/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
* using Montgomery point multiplication algorithm Mxy() in appendix of
* Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
* Returns:
* 0 on error
* 1 if return value should be the point at infinity
* 2 otherwise
*/
static int
gf2m_Mxy(const mp_int *pp, const unsigned int p[], const mp_int *a,
const mp_int *b, const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
mp_int *x2, mp_int *z2)
{
mp_err err = MP_OKAY;
int ret;
mp_int t3, t4, t5;
MP_DIGITS(&t3) = 0;
MP_DIGITS(&t4) = 0;
MP_DIGITS(&t5) = 0;
CHECK_MPI_OK( mp_init(&t3) );
CHECK_MPI_OK( mp_init(&t4) );
CHECK_MPI_OK( mp_init(&t5) );
if (mp_cmp_z(z1) == 0) {
mp_zero(x2);
mp_zero(z2);
ret = 1;
goto cleanup;
}
if (mp_cmp_z(z2) == 0) {
CHECK_MPI_OK( mp_copy(x, x2) );
CHECK_MPI_OK( mp_badd(x, y, z2) );
ret = 2;
goto cleanup;
}
mp_set(&t5, 0x1);
CHECK_MPI_OK( mp_bmulmod(z1, z2, p, &t3) );
CHECK_MPI_OK( mp_bmulmod(z1, x, p, z1) );
CHECK_MPI_OK( mp_badd(z1, x1, z1) );
CHECK_MPI_OK( mp_bmulmod(z2, x, p, z2) );
CHECK_MPI_OK( mp_bmulmod(z2, x1, p, x1) );
CHECK_MPI_OK( mp_badd(z2, x2, z2) );
CHECK_MPI_OK( mp_bmulmod(z2, z1, p, z2) );
CHECK_MPI_OK( mp_bsqrmod(x, p, &t4) );
CHECK_MPI_OK( mp_badd(&t4, y, &t4) );
CHECK_MPI_OK( mp_bmulmod(&t4, &t3, p, &t4) );
CHECK_MPI_OK( mp_badd(&t4, z2, &t4) );
CHECK_MPI_OK( mp_bmulmod(&t3, x, p, &t3) );
CHECK_MPI_OK( mp_bdivmod(&t5, &t3, pp, p, &t3) );
CHECK_MPI_OK( mp_bmulmod(&t3, &t4, p, &t4) );
CHECK_MPI_OK( mp_bmulmod(x1, &t3, p, x2) );
CHECK_MPI_OK( mp_badd(x2, x, z2) );
CHECK_MPI_OK( mp_bmulmod(z2, &t4, p, z2) );
CHECK_MPI_OK( mp_badd(z2, y, z2) );
ret = 2;
cleanup:
mp_clear(&t3);
mp_clear(&t4);
mp_clear(&t5);
if (err == MP_OKAY) {
return ret;
} else {
return 0;
}
}
/* Computes R = nP based on algorithm 2P of
* Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
* Elliptic curve points P and R can be identical.
* Uses Montgomery projective coordinates.
*/
mp_err
GF2m_ec_pt_mul_mont(const mp_int *pp, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int x1, x2, z1, z2;
int i, j;
mp_digit top_bit, mask;
unsigned int *p;
int p_size;
MP_DIGITS(&x1) = 0;
MP_DIGITS(&x2) = 0;
MP_DIGITS(&z1) = 0;
MP_DIGITS(&z2) = 0;
CHECK_MPI_OK( mp_init(&x1) );
CHECK_MPI_OK( mp_init(&x2) );
CHECK_MPI_OK( mp_init(&z1) );
CHECK_MPI_OK( mp_init(&z2) );
p_size = mp_bpoly2arr(pp, p, 0) + 1;
p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size));
if (p == NULL) goto cleanup;
mp_bpoly2arr(pp, p, p_size);
/* if result should be point at infinity */
if ((mp_cmp_z(n) == 0) || (GF2m_ec_pt_is_inf_aff(px, py) == MP_YES)) {
CHECK_MPI_OK( GF2m_ec_pt_set_inf_aff(rx, ry) );
goto cleanup;
}
CHECK_MPI_OK( mp_copy(rx, &x2) ); /* x2 = rx */
CHECK_MPI_OK( mp_copy(ry, &z2) ); /* z2 = ry */
CHECK_MPI_OK( mp_copy(px, &x1) ); /* x1 = px */
mp_set(&z1, 0x1); /* z1 = 1 */
CHECK_MPI_OK( mp_bsqrmod(&x1, p, &z2) ); /* z2 = x1^2 = x2^2 */
CHECK_MPI_OK( mp_bsqrmod(&z2, p, &x2) );
CHECK_MPI_OK( mp_badd(&x2, b, &x2) ); /* x2 = px^4 + b */
/* find top-most bit and go one past it */
i = MP_USED(n) - 1;
j = MP_DIGIT_BIT - 1;
top_bit = 1;
top_bit <<= MP_DIGIT_BIT - 1;
mask = top_bit;
while (!(MP_DIGITS(n)[i] & mask)) {
mask >>= 1;
j--;
}
mask >>= 1; j--;
/* if top most bit was at word break, go to next word */
if (!mask) {
i--;
j = MP_DIGIT_BIT - 1;
mask = top_bit;
}
for (; i >= 0; i--) {
for (; j >= 0; j--) {
if (MP_DIGITS(n)[i] & mask) {
CHECK_MPI_OK( gf2m_Madd(pp, p, a, b, px, &x1, &z1, &x2, &z2) );
CHECK_MPI_OK( gf2m_Mdouble(pp, p, a, b, &x2, &z2) );
} else {
CHECK_MPI_OK( gf2m_Madd(pp, p, a, b, px, &x2, &z2, &x1, &z1) );
CHECK_MPI_OK( gf2m_Mdouble(pp, p, a, b, &x1, &z1) );
}
mask >>= 1;
}
j = MP_DIGIT_BIT - 1;
mask = top_bit;
}
/* convert out of "projective" coordinates */
i = gf2m_Mxy(pp, p, a, b, px, py, &x1, &z1, &x2, &z2);
if (i == 0) {
err = MP_BADARG;
goto cleanup;
} else if (i == 1) {
CHECK_MPI_OK( GF2m_ec_pt_set_inf_aff(rx, ry) );
} else {
CHECK_MPI_OK( mp_copy(&x2, rx) );
CHECK_MPI_OK( mp_copy(&z2, ry) );
}
cleanup:
mp_clear(&x1);
mp_clear(&x2);
mp_clear(&z1);
mp_clear(&z2);
free(p);
return err;
}
#endif /* NSS_ENABLE_ECC */

View File

@@ -1,96 +0,0 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the elliptic curve math library for binary polynomial
* field curves.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Douglas Stebila <douglas@stebila.ca>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifndef __gf2m_ecl_h_
#define __gf2m_ecl_h_
#ifdef NSS_ENABLE_ECC
#include "secmpi.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
mp_err GF2m_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py);
/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
mp_err GF2m_ec_pt_set_inf_aff(mp_int *px, mp_int *py);
/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx, qy).
* Uses affine coordinates.
*/
mp_err GF2m_ec_pt_add_aff(const mp_int *pp, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry);
/* Computes R = P - Q. Uses affine coordinates. */
mp_err GF2m_ec_pt_sub_aff(const mp_int *pp, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry);
/* Computes R = 2P. Uses affine coordinates. */
mp_err GF2m_ec_pt_dbl_aff(const mp_int *pp, const mp_int *a,
const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry);
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the irreducible that
* determines the field GF2m. Uses affine coordinates.
*/
mp_err GF2m_ec_pt_mul_aff(const mp_int *pp, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry);
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the irreducible that
* determines the field GF2m. Uses Montgomery projective coordinates.
*/
mp_err GF2m_ec_pt_mul_mont(const mp_int *pp, const mp_int *a,
const mp_int *b, const mp_int *px, const mp_int *py,
const mp_int *n, mp_int *rx, mp_int *ry);
#define GF2m_ec_pt_is_inf(px, py) GF2m_ec_pt_is_inf_aff((px), (py))
#define GF2m_ec_pt_add(p, a, px, py, qx, qy, rx, ry) \
GF2m_ec_pt_add_aff((p), (a), (px), (py), (qx), (qy), (rx), (ry))
#define GF2m_ECL_MONTGOMERY
#ifdef GF2m_ECL_AFFINE
#define GF2m_ec_pt_mul(pp, a, b, px, py, n, rx, ry) \
GF2m_ec_pt_mul_aff((pp), (a), (b), (px), (py), (n), (rx), (ry))
#elif defined(GF2m_ECL_MONTGOMERY)
#define GF2m_ec_pt_mul(pp, a, b, px, py, n, rx, ry) \
GF2m_ec_pt_mul_mont((pp), (a), (b), (px), (py), (n), (rx), (ry))
#endif /* GF2m_ECL_AFFINE or GF2m_ECL_MONTGOMERY */
#endif /* NSS_ENABLE_ECC */
#endif /* __gf2m_ecl_h_ */

View File

@@ -1,647 +0,0 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the elliptic curve math library for prime
* field curves.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Sheueling Chang Shantz <sheueling.chang@sun.com> and
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
*
* Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
* Nils Larsch <nla@trustcenter.de>, and
* Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifdef NSS_ENABLE_ECC
/*
* GFp_ecl.c: Contains an implementation of elliptic curve math library
* for curves over GFp.
*
* XXX Can be moved to a separate subdirectory later.
*
*/
#include "GFp_ecl.h"
#include "mpi/mplogic.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
mp_err
GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py)
{
if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
return MP_YES;
} else {
return MP_NO;
}
}
/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
mp_err
GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py)
{
mp_zero(px);
mp_zero(py);
return MP_OKAY;
}
/* Computes R = P + Q based on IEEE P1363 A.10.1.
* Elliptic curve points P, Q, and R can all be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int lambda, temp, xtemp, ytemp;
CHECK_MPI_OK( mp_init(&lambda) );
CHECK_MPI_OK( mp_init(&temp) );
CHECK_MPI_OK( mp_init(&xtemp) );
CHECK_MPI_OK( mp_init(&ytemp) );
/* if P = inf, then R = Q */
if (GFp_ec_pt_is_inf_aff(px, py) == 0) {
CHECK_MPI_OK( mp_copy(qx, rx) );
CHECK_MPI_OK( mp_copy(qy, ry) );
err = MP_OKAY;
goto cleanup;
}
/* if Q = inf, then R = P */
if (GFp_ec_pt_is_inf_aff(qx, qy) == 0) {
CHECK_MPI_OK( mp_copy(px, rx) );
CHECK_MPI_OK( mp_copy(py, ry) );
err = MP_OKAY;
goto cleanup;
}
/* if px != qx, then lambda = (py-qy) / (px-qx) */
if (mp_cmp(px, qx) != 0) {
CHECK_MPI_OK( mp_submod(py, qy, p, &ytemp) );
CHECK_MPI_OK( mp_submod(px, qx, p, &xtemp) );
CHECK_MPI_OK( mp_invmod(&xtemp, p, &xtemp) );
CHECK_MPI_OK( mp_mulmod(&ytemp, &xtemp, p, &lambda) );
} else {
/* if py != qy or qy = 0, then R = inf */
if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
}
/* lambda = (3qx^2+a) / (2qy) */
CHECK_MPI_OK( mp_sqrmod(qx, p, &xtemp) );
mp_set(&temp, 0x3);
CHECK_MPI_OK( mp_mulmod(&xtemp, &temp, p, &xtemp) );
CHECK_MPI_OK( mp_addmod(&xtemp, a, p, &xtemp) );
mp_set(&temp, 0x2);
CHECK_MPI_OK( mp_mulmod(qy, &temp, p, &ytemp) );
CHECK_MPI_OK( mp_invmod(&ytemp, p, &ytemp) );
CHECK_MPI_OK( mp_mulmod(&xtemp, &ytemp, p, &lambda) );
}
/* rx = lambda^2 - px - qx */
CHECK_MPI_OK( mp_sqrmod(&lambda, p, &xtemp) );
CHECK_MPI_OK( mp_submod(&xtemp, px, p, &xtemp) );
CHECK_MPI_OK( mp_submod(&xtemp, qx, p, &xtemp) );
/* ry = (x1-x2) * lambda - y1 */
CHECK_MPI_OK( mp_submod(qx, &xtemp, p, &ytemp) );
CHECK_MPI_OK( mp_mulmod(&ytemp, &lambda, p, &ytemp) );
CHECK_MPI_OK( mp_submod(&ytemp, qy, p, &ytemp) );
CHECK_MPI_OK( mp_copy(&xtemp, rx) );
CHECK_MPI_OK( mp_copy(&ytemp, ry) );
cleanup:
mp_clear(&lambda);
mp_clear(&temp);
mp_clear(&xtemp);
mp_clear(&ytemp);
return err;
}
/* Computes R = P - Q.
* Elliptic curve points P, Q, and R can all be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int nqy;
MP_DIGITS(&nqy) = 0;
CHECK_MPI_OK( mp_init(&nqy) );
/* nqy = -qy */
CHECK_MPI_OK( mp_neg(qy, &nqy) );
err = GFp_ec_pt_add_aff(p, a, px, py, qx, &nqy, rx, ry);
cleanup:
mp_clear(&nqy);
return err;
}
/* Computes R = 2P.
* Elliptic curve points P and R can be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, mp_int *rx, mp_int *ry)
{
return GFp_ec_pt_add_aff(p, a, px, py, px, py, rx, ry);
}
/* Gets the i'th bit in the binary representation of a.
* If i >= length(a), then return 0.
* (The above behaviour differs from mpl_get_bit, which
* causes an error if i >= length(a).)
*/
#define MP_GET_BIT(a, i) \
((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
/* Computes R = nP based on IEEE P1363 A.10.3.
* Elliptic curve points P and R can be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n, mp_int *rx,
mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int k, k3, qx, qy, sx, sy;
int b1, b3, i, l;
MP_DIGITS(&k) = 0;
MP_DIGITS(&k3) = 0;
MP_DIGITS(&qx) = 0;
MP_DIGITS(&qy) = 0;
MP_DIGITS(&sx) = 0;
MP_DIGITS(&sy) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&k3) );
CHECK_MPI_OK( mp_init(&qx) );
CHECK_MPI_OK( mp_init(&qy) );
CHECK_MPI_OK( mp_init(&sx) );
CHECK_MPI_OK( mp_init(&sy) );
/* if n = 0 then r = inf */
if (mp_cmp_z(n) == 0) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
}
/* Q = P, k = n */
CHECK_MPI_OK( mp_copy(px, &qx) );
CHECK_MPI_OK( mp_copy(py, &qy) );
CHECK_MPI_OK( mp_copy(n, &k) );
/* if n < 0 Q = -Q, k = -k */
if (mp_cmp_z(n) < 0) {
CHECK_MPI_OK( mp_neg(&qy, &qy) );
CHECK_MPI_OK( mp_mod(&qy, p, &qy) );
CHECK_MPI_OK( mp_neg(&k, &k) );
CHECK_MPI_OK( mp_mod(&k, p, &k) );
}
#ifdef EC_DEBUG /* basic double and add method */
l = mpl_significant_bits(&k) - 1;
mp_zero(&sx);
mp_zero(&sy);
for (i = l; i >= 0; i--) {
/* if k_i = 1, then S = S + Q */
if (mpl_get_bit(&k, i) != 0) {
CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy,
&qx, &qy, &sx, &sy) );
}
if (i > 0) {
/* S = 2S */
CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) );
}
}
#else /* double and add/subtract method from standard */
/* k3 = 3 * k */
mp_set(&k3, 0x3);
CHECK_MPI_OK( mp_mul(&k, &k3, &k3) );
/* S = Q */
CHECK_MPI_OK( mp_copy(&qx, &sx) );
CHECK_MPI_OK( mp_copy(&qy, &sy) );
/* l = index of high order bit in binary representation of 3*k */
l = mpl_significant_bits(&k3) - 1;
/* for i = l-1 downto 1 */
for (i = l - 1; i >= 1; i--) {
/* S = 2S */
CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) );
b3 = MP_GET_BIT(&k3, i);
b1 = MP_GET_BIT(&k, i);
/* if k3_i = 1 and k_i = 0, then S = S + Q */
if ((b3 == 1) && (b1 == 0)) {
CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy,
&qx, &qy, &sx, &sy) );
/* if k3_i = 0 and k_i = 1, then S = S - Q */
} else if ((b3 == 0) && (b1 == 1)) {
CHECK_MPI_OK( GFp_ec_pt_sub_aff(p, a, &sx, &sy,
&qx, &qy, &sx, &sy) );
}
}
#endif
/* output S */
CHECK_MPI_OK( mp_copy(&sx, rx) );
CHECK_MPI_OK( mp_copy(&sy, ry) );
cleanup:
mp_clear(&k);
mp_clear(&k3);
mp_clear(&qx);
mp_clear(&qy);
mp_clear(&sx);
mp_clear(&sy);
return err;
}
/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
* affine coordinates R(rx, ry). P and R can share x and y coordinates.
*/
mp_err
GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
const mp_int *p, mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int z1, z2, z3;
MP_DIGITS(&z1) = 0;
MP_DIGITS(&z2) = 0;
MP_DIGITS(&z3) = 0;
CHECK_MPI_OK( mp_init(&z1) );
CHECK_MPI_OK( mp_init(&z2) );
CHECK_MPI_OK( mp_init(&z3) );
/* if point at infinity, then set point at infinity and exit */
if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) {
CHECK_MPI_OK( GFp_ec_pt_set_inf_aff(rx, ry) );
goto cleanup;
}
/* transform (px, py, pz) into (px / pz^2, py / pz^3) */
if (mp_cmp_d(pz, 1) == 0) {
CHECK_MPI_OK( mp_copy(px, rx) );
CHECK_MPI_OK( mp_copy(py, ry) );
} else {
CHECK_MPI_OK( mp_invmod(pz, p, &z1) );
CHECK_MPI_OK( mp_sqrmod(&z1, p, &z2) );
CHECK_MPI_OK( mp_mulmod(&z1, &z2, p, &z3) );
CHECK_MPI_OK( mp_mulmod(px, &z2, p, rx) );
CHECK_MPI_OK( mp_mulmod(py, &z3, p, ry) );
}
cleanup:
mp_clear(&z1);
mp_clear(&z2);
mp_clear(&z3);
return err;
}
/* Checks if point P(px, py, pz) is at infinity.
* Uses Jacobian coordinates.
*/
mp_err
GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
{
return mp_cmp_z(pz);
}
/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
* coordinates.
*/
mp_err
GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
{
mp_zero(pz);
return MP_OKAY;
}
/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and
* Q is (qx, qy, qz). Elliptic curve points P, Q, and R can all be
* identical. Uses Jacobian coordinates.
*
* This routine implements Point Addition in the Jacobian Projective
* space as described in the paper "Efficient elliptic curve exponentiation
* using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
*/
mp_err
GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *pz, const mp_int *qx,
const mp_int *qy, const mp_int *qz, mp_int *rx, mp_int *ry, mp_int *rz)
{
mp_err err = MP_OKAY;
mp_int n0, u1, u2, s1, s2, H, G;
MP_DIGITS(&n0) = 0;
MP_DIGITS(&u1) = 0;
MP_DIGITS(&u2) = 0;
MP_DIGITS(&s1) = 0;
MP_DIGITS(&s2) = 0;
MP_DIGITS(&H) = 0;
MP_DIGITS(&G) = 0;
CHECK_MPI_OK( mp_init(&n0) );
CHECK_MPI_OK( mp_init(&u1) );
CHECK_MPI_OK( mp_init(&u2) );
CHECK_MPI_OK( mp_init(&s1) );
CHECK_MPI_OK( mp_init(&s2) );
CHECK_MPI_OK( mp_init(&H) );
CHECK_MPI_OK( mp_init(&G) );
/* Use point double if pointers are equal. */
if ((px == qx) && (py == qy) && (pz == qz)) {
err = GFp_ec_pt_dbl_jac(p, a, px, py, pz, rx, ry, rz);
goto cleanup;
}
/* If either P or Q is the point at infinity, then return
* the other point
*/
if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) {
CHECK_MPI_OK( mp_copy(qx, rx) );
CHECK_MPI_OK( mp_copy(qy, ry) );
CHECK_MPI_OK( mp_copy(qz, rz) );
goto cleanup;
}
if (GFp_ec_pt_is_inf_jac(qx, qy, qz) == MP_YES) {
CHECK_MPI_OK( mp_copy(px, rx) );
CHECK_MPI_OK( mp_copy(py, ry) );
CHECK_MPI_OK( mp_copy(pz, rz) );
goto cleanup;
}
/* Compute u1 = px * qz^2, s1 = py * qz^3 */
if (mp_cmp_d(qz, 1) == 0) {
CHECK_MPI_OK( mp_copy(px, &u1) );
CHECK_MPI_OK( mp_copy(py, &s1) );
} else {
CHECK_MPI_OK( mp_sqrmod(qz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(px, &n0, p, &u1) );
CHECK_MPI_OK( mp_mulmod(&n0, qz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(py, &n0, p, &s1) );
}
/* Compute u2 = qx * pz^2, s2 = qy * pz^3 */
if (mp_cmp_d(pz, 1) == 0) {
CHECK_MPI_OK( mp_copy(qx, &u2) );
CHECK_MPI_OK( mp_copy(qy, &s2) );
} else {
CHECK_MPI_OK( mp_sqrmod(pz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(qx, &n0, p, &u2) );
CHECK_MPI_OK( mp_mulmod(&n0, pz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(qy, &n0, p, &s2) );
}
/* Compute H = u2 - u1 ; G = s2 - s1 */
CHECK_MPI_OK( mp_submod(&u2, &u1, p, &H) );
CHECK_MPI_OK( mp_submod(&s2, &s1, p, &G) );
if (mp_cmp_z(&H) == 0) {
if (mp_cmp_z(&G) == 0) {
/* P = Q; double */
err = GFp_ec_pt_dbl_jac(p, a, px, py, pz,
rx, ry, rz);
goto cleanup;
} else {
/* P = -Q; return point at infinity */
CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) );
goto cleanup;
}
}
/* rz = pz * qz * H */
if (mp_cmp_d(pz, 1) == 0) {
if (mp_cmp_d(qz, 1) == 0) {
/* if pz == qz == 1, then rz = H */
CHECK_MPI_OK( mp_copy(&H, rz) );
} else {
CHECK_MPI_OK( mp_mulmod(qz, &H, p, rz) );
}
} else {
if (mp_cmp_d(qz, 1) == 0) {
CHECK_MPI_OK( mp_mulmod(pz, &H, p, rz) );
} else {
CHECK_MPI_OK( mp_mulmod(pz, qz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(&n0, &H, p, rz) );
}
}
/* rx = G^2 - H^3 - 2 * u1 * H^2 */
CHECK_MPI_OK( mp_sqrmod(&G, p, rx) );
CHECK_MPI_OK( mp_sqrmod(&H, p, &n0) );
CHECK_MPI_OK( mp_mulmod(&n0, &u1, p, &u1) );
CHECK_MPI_OK( mp_addmod(&u1, &u1, p, &u2) );
CHECK_MPI_OK( mp_mulmod(&H, &n0, p, &H) );
CHECK_MPI_OK( mp_submod(rx, &H, p, rx) );
CHECK_MPI_OK( mp_submod(rx, &u2, p, rx) );
/* ry = - s1 * H^3 + G * (u1 * H^2 - rx) */
/* (formula based on values of variables before block above) */
CHECK_MPI_OK( mp_submod(&u1, rx, p, &u1) );
CHECK_MPI_OK( mp_mulmod(&G, &u1, p, ry) );
CHECK_MPI_OK( mp_mulmod(&s1, &H, p, &s1) );
CHECK_MPI_OK( mp_submod(ry, &s1, p, ry) );
cleanup:
mp_clear(&n0);
mp_clear(&u1);
mp_clear(&u2);
mp_clear(&s1);
mp_clear(&s2);
mp_clear(&H);
mp_clear(&G);
return err;
}
/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
* Jacobian coordinates.
*
* This routine implements Point Doubling in the Jacobian Projective
* space as described in the paper "Efficient elliptic curve exponentiation
* using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
*/
mp_err
GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *pz, mp_int *rx, mp_int *ry, mp_int *rz)
{
mp_err err = MP_OKAY;
mp_int t0, t1, M, S;
MP_DIGITS(&t0) = 0;
MP_DIGITS(&t1) = 0;
MP_DIGITS(&M) = 0;
MP_DIGITS(&S) = 0;
CHECK_MPI_OK( mp_init(&t0) );
CHECK_MPI_OK( mp_init(&t1) );
CHECK_MPI_OK( mp_init(&M) );
CHECK_MPI_OK( mp_init(&S) );
if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) {
CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) );
goto cleanup;
}
if (mp_cmp_d(pz, 1) == 0) {
/* M = 3 * px^2 + a */
CHECK_MPI_OK( mp_sqrmod(px, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) );
CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, a, p, &M) );
} else if (mp_cmp_int(a, -3) == 0) {
/* M = 3 * (px + pz^2) * (px - pz) */
CHECK_MPI_OK( mp_sqrmod(pz, p, &M) );
CHECK_MPI_OK( mp_addmod(px, &M, p, &t0) );
CHECK_MPI_OK( mp_submod(px, &M, p, &t1) );
CHECK_MPI_OK( mp_mulmod(&t0, &t1, p, &M) );
CHECK_MPI_OK( mp_addmod(&M, &M, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, &M, p, &M) );
} else {
CHECK_MPI_OK( mp_sqrmod(px, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) );
CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) );
CHECK_MPI_OK( mp_sqrmod(pz, p, &M) );
CHECK_MPI_OK( mp_sqrmod(&M, p, &M) );
CHECK_MPI_OK( mp_mulmod(&M, a, p, &M) );
CHECK_MPI_OK( mp_addmod(&M, &t0, p, &M) );
}
/* rz = 2 * py * pz */
if (mp_cmp_d(pz, 1) == 0) {
CHECK_MPI_OK( mp_addmod(py, py, p, rz) );
CHECK_MPI_OK( mp_sqrmod(rz, p, &t0) );
} else {
CHECK_MPI_OK( mp_addmod(py, py, p, &t0) );
CHECK_MPI_OK( mp_mulmod(&t0, pz, p, rz) );
CHECK_MPI_OK( mp_sqrmod(&t0, p, &t0) );
}
/* S = 4 * px * py^2 = pz * (2 * py)^2 */
CHECK_MPI_OK( mp_mulmod(px, &t0, p, &S) );
/* rx = M^2 - 2 * S */
CHECK_MPI_OK( mp_addmod(&S, &S, p, &t1) );
CHECK_MPI_OK( mp_sqrmod(&M, p, rx) );
CHECK_MPI_OK( mp_submod(rx, &t1, p, rx) );
/* ry = M * (S - rx) - 8 * py^4 */
CHECK_MPI_OK( mp_sqrmod(&t0, p, &t1) );
if (mp_isodd(&t1)) {
CHECK_MPI_OK( mp_add(&t1, p, &t1) );
}
CHECK_MPI_OK( mp_div_2(&t1, &t1) );
CHECK_MPI_OK( mp_submod(&S, rx, p, &S) );
CHECK_MPI_OK( mp_mulmod(&M, &S, p, &M) );
CHECK_MPI_OK( mp_submod(&M, &t1, p, ry) );
cleanup:
mp_clear(&t0);
mp_clear(&t1);
mp_clear(&M);
mp_clear(&S);
return err;
}
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the prime that
* determines the field GFp. Elliptic curve points P and R can be
* identical. Uses Jacobian coordinates.
*/
mp_err
GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int k, qx, qy, qz, sx, sy, sz;
int i, l;
MP_DIGITS(&k) = 0;
MP_DIGITS(&qx) = 0;
MP_DIGITS(&qy) = 0;
MP_DIGITS(&qz) = 0;
MP_DIGITS(&sx) = 0;
MP_DIGITS(&sy) = 0;
MP_DIGITS(&sz) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&qx) );
CHECK_MPI_OK( mp_init(&qy) );
CHECK_MPI_OK( mp_init(&qz) );
CHECK_MPI_OK( mp_init(&sx) );
CHECK_MPI_OK( mp_init(&sy) );
CHECK_MPI_OK( mp_init(&sz) );
/* if n = 0 then r = inf */
if (mp_cmp_z(n) == 0) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
/* if n < 0 then out of range error */
} else if (mp_cmp_z(n) < 0) {
err = MP_RANGE;
goto cleanup;
}
/* Q = P, k = n */
CHECK_MPI_OK( mp_copy(px, &qx) );
CHECK_MPI_OK( mp_copy(py, &qy) );
CHECK_MPI_OK( mp_set_int(&qz, 1) );
CHECK_MPI_OK( mp_copy(n, &k) );
/* double and add method */
l = mpl_significant_bits(&k) - 1;
mp_zero(&sx);
mp_zero(&sy);
mp_zero(&sz);
for (i = l; i >= 0; i--) {
/* if k_i = 1, then S = S + Q */
if (MP_GET_BIT(&k, i) != 0) {
CHECK_MPI_OK( GFp_ec_pt_add_jac(p, a, &sx, &sy, &sz,
&qx, &qy, &qz, &sx, &sy, &sz) );
}
if (i > 0) {
/* S = 2S */
CHECK_MPI_OK( GFp_ec_pt_dbl_jac(p, a, &sx, &sy, &sz,
&sx, &sy, &sz) );
}
}
/* convert result S to affine coordinates */
CHECK_MPI_OK( GFp_ec_pt_jac2aff(&sx, &sy, &sz, p, rx, ry) );
cleanup:
mp_clear(&k);
mp_clear(&qx);
mp_clear(&qy);
mp_clear(&qz);
mp_clear(&sx);
mp_clear(&sy);
mp_clear(&sz);
return err;
}
#endif /* NSS_ENABLE_ECC */

View File

@@ -1,126 +0,0 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the elliptic curve math library for prime
* field curves.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifndef __gfp_ecl_h_
#define __gfp_ecl_h_
#ifdef NSS_ENABLE_ECC
#include "secmpi.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
extern mp_err GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py);
/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
extern mp_err GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py);
/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx, qy).
* Uses affine coordinates.
*/
extern mp_err GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry);
/* Computes R = P - Q. Uses affine coordinates. */
extern mp_err GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry);
/* Computes R = 2P. Uses affine coordinates. */
extern mp_err GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry);
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the prime that
* determines the field GFp. Uses affine coordinates.
*/
extern mp_err GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a,
const mp_int *b, const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry);
/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
* affine coordinates R(rx, ry).
*/
extern mp_err GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py,
const mp_int *pz, const mp_int *p, mp_int *rx, mp_int *ry);
/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
* coordinates.
*/
extern mp_err GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py,
const mp_int *pz);
/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
* coordinates.
*/
extern mp_err GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz);
/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and
* Q is (qx, qy, qz). Uses Jacobian coordinates.
*/
extern mp_err GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *pz,
const mp_int *qx, const mp_int *qy, const mp_int *qz,
mp_int *rx, mp_int *ry, mp_int *rz);
/* Computes R = 2P. Uses Jacobian coordinates. */
extern mp_err GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *pz,
mp_int *rx, mp_int *ry, mp_int *rz);
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the prime that
* determines the field GFp. Uses Jacobian coordinates.
*/
mp_err GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry);
#define GFp_ec_pt_is_inf(px, py) GFp_ec_pt_is_inf_aff((px), (py))
#define GFp_ec_pt_add(p, a, px, py, qx, qy, rx, ry) \
GFp_ec_pt_add_aff((p), (a), (px), (py), (qx), (qy), (rx), (ry))
#define GFp_ECL_JACOBIAN
#ifdef GFp_ECL_AFFINE
#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \
GFp_ec_pt_mul_aff((p), (a), (b), (px), (py), (n), (rx), (ry))
#elif defined(GFp_ECL_JACOBIAN)
#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \
GFp_ec_pt_mul_jac((p), (a), (b), (px), (py), (n), (rx), (ry))
#endif /* GFp_ECL_AFFINE or GFp_ECL_JACOBIAN*/
#endif /* NSS_ENABLE_ECC */
#endif /* __gfp_ecl_h_ */

View File

@@ -1,339 +0,0 @@
#! gmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
-include config.mk
ifdef USE_64
DEFINES += -DNSS_USE_64
endif
ifdef USE_HYBRID
DEFINES += -DNSS_USE_HYBRID
endif
# des.c wants _X86_ defined for intel CPUs.
# coreconf does this for windows, but not for Linux, FreeBSD, etc.
ifeq ($(CPU_ARCH),x86)
ifneq (,$(filter-out WIN%,$(OS_TARGET)))
OS_REL_CFLAGS += -D_X86_
endif
endif
ifeq ($(OS_TARGET),OSF1)
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_NO_MP_WORD
MPI_SRCS += mpvalpha.c
endif
ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET))) #omits WIN16 and WINCE
ifdef NS_USE_GCC
# Ideally, we want to use assembler
# ASFILES = mpi_x86.s
# DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE \
# -DMP_ASSEMBLY_DIV_2DX1D
# but we haven't figured out how to make it work, so we are not
# using assembler right now.
ASFILES =
DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT
else
ASFILES = mpi_x86.asm
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
endif
ifdef BUILD_OPT
ifndef NS_USE_GCC
OPTIMIZER += -Ox # maximum optimization for freebl
endif
endif
endif
ifeq ($(OS_TARGET),WINCE)
DEFINES += -DMP_ARGCHK=0 # no assert in WinCE
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
endif
ifdef XP_OS2_VACPP
ASFILES = mpi_x86.asm
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
endif
ifeq ($(OS_TARGET),IRIX)
ifeq ($(USE_N32),1)
ASFILES = mpi_mips.s
ifeq ($(NS_USE_GCC),1)
ASFLAGS = -Wp,-P -Wp,-traditional -O -mips3
else
ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3
endif
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
DEFINES += -DMP_USE_UINT_DIGIT
else
endif
endif
ifeq ($(OS_TARGET),Linux)
ifeq ($(CPU_ARCH),x86)
ASFILES = mpi_x86.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
endif
endif
ifeq ($(OS_TARGET),AIX)
DEFINES += -DMP_USE_UINT_DIGIT
ifndef USE_64
DEFINES += -DMP_NO_DIV_WORD -DMP_NO_ADD_WORD -DMP_NO_SUB_WORD
endif
endif
ifeq ($(OS_TARGET), HP-UX)
ifneq ($(OS_TEST), ia64)
MKSHLIB += +k +vshlibunsats -u FREEBL_GetVector +e FREEBL_GetVector
ifndef FREEBL_EXTENDED_BUILD
ifdef USE_PURE_32
# build for DA1.1 (HP PA 1.1) pure 32 bit model
DEFINES += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
else
ifdef USE_64
# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 32-bit digits
MPI_SRCS += mpi_hp.c
ASFILES += hpma512.s hppa20.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
else
# this builds for DA2.0 (HP PA 2.0 Narrow) hybrid model
# (the 32-bit ABI with 64-bit registers) using 32-bit digits
MPI_SRCS += mpi_hp.c
ASFILES += hpma512.s hppa20.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
# This is done in coreconf by defining USE_LONG_LONGS
# OS_CFLAGS += -Aa +e +DA2.0 +DS2.0
endif
endif
endif
endif
endif
# Note: -xarch=v8 or v9 is now done in coreconf
ifeq ($(OS_TARGET),SunOS)
ifeq ($(CPU_ARCH),sparc)
ifndef NS_USE_GCC
ifdef USE_HYBRID
OS_CFLAGS += -xchip=ultra2
endif
endif
ifeq (5.5.1,$(firstword $(sort 5.5.1 $(OS_RELEASE))))
SYSV_SPARC = 1
endif
ifeq ($(SYSV_SPARC),1)
SOLARIS_AS = /usr/ccs/bin/as
ifdef NS_USE_GCC
ifdef GCC_USE_GNU_LD
MKSHLIB += -Wl,-Bsymbolic,-z,defs,-z,now,-z,text,--version-script,mapfile.Solaris
else
MKSHLIB += -Wl,-B,symbolic,-z,defs,-z,now,-z,text,-M,mapfile.Solaris
endif
else
MKSHLIB += -B symbolic -z defs -z now -z text -M mapfile.Solaris
endif
ifdef USE_PURE_32
# this builds for Sparc v8 pure 32-bit architecture
DEFINES += -DMP_USE_LONG_LONG_MULTIPLY -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
else
ifdef USE_64
# this builds for Sparc v9a pure 64-bit architecture
MPI_SRCS += mpi_sparc.c
ASFILES = mpv_sparcv9.s montmulfv9.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_USING_MONT_MULF
DEFINES += -DMP_USE_UINT_DIGIT
# MPI_SRCS += mpv_sparc.c
# removed -xdepend from the following line
SOLARIS_FLAGS = -fast -xO5 -xrestrict=%all -xchip=ultra -xarch=v9a -KPIC -mt
SOLARIS_AS_FLAGS = -xarch=v9a -K PIC
else
# this builds for Sparc v8+a hybrid architecture, 64-bit registers, 32-bit ABI
MPI_SRCS += mpi_sparc.c
ASFILES = mpv_sparcv8.s montmulfv8.s
DEFINES += -DMP_NO_MP_WORD -DMP_ASSEMBLY_MULTIPLY -DMP_USING_MONT_MULF
DEFINES += -DMP_USE_UINT_DIGIT
SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC
# ASM_SUFFIX = .S
endif
endif
endif
else
# Solaris x86
DEFINES += -D_X86_
DEFINES += -DMP_USE_UINT_DIGIT
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
ASFILES = mpi_i86pc.s
ifdef NS_USE_GCC
LD = gcc
AS = gcc
ASFLAGS =
endif
endif
endif
$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c mac_rand.c os2_rand.c
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
export:: private_export
rijndael_tables:
$(CC) -o $(OBJDIR)/make_rijndael_tab rijndael_tables.c \
$(DEFINES) $(INCLUDES) $(OBJDIR)/libfreebl.a
$(OBJDIR)/make_rijndael_tab
ifdef MOZILLA_BSAFE_BUILD
private_export::
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
rm -f $(DIST)/lib/bsafe$(BSAFEVER).lib
endif
$(NSINSTALL) -R $(BSAFEPATH) $(DIST)/lib
endif
ifdef USE_PURE_32
vpath %.h $(FREEBL_PARENT)/mpi:$(FREEBL_PARENT)
vpath %.c $(FREEBL_PARENT)/mpi:$(FREEBL_PARENT)
vpath %.S $(FREEBL_PARENT)/mpi:$(FREEBL_PARENT)
vpath %.s $(FREEBL_PARENT)/mpi:$(FREEBL_PARENT)
vpath %.asm $(FREEBL_PARENT)/mpi:$(FREEBL_PARENT)
INCLUDES += -I$(FREEBL_PARENT) -I$(FREEBL_PARENT)/mpi
else
vpath %.h mpi
vpath %.c mpi
vpath %.S mpi
vpath %.s mpi
vpath %.asm mpi
INCLUDES += -Impi
endif
DEFINES += -DMP_API_COMPATIBLE
MPI_USERS = dh.c pqg.c dsa.c rsa.c ec.c GFp_ecl.c
MPI_OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_SRCS:.c=$(OBJ_SUFFIX)))
MPI_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_USERS:.c=$(OBJ_SUFFIX)))
$(MPI_OBJS): $(MPI_HDRS)
$(OBJDIR)/$(PROG_PREFIX)mpprime$(OBJ_SUFFIX): primes.c
$(OBJDIR)/ldvector$(OBJ_SUFFIX) $(OBJDIR)/loader$(OBJ_SUFFIX) : loader.h
ifeq ($(SYSV_SPARC),1)
$(OBJDIR)/mpv_sparcv8.o $(OBJDIR)/montmulfv8.o : $(OBJDIR)/%.o : %.s
@$(MAKE_OBJDIR)
$(SOLARIS_AS) -o $@ $(SOLARIS_AS_FLAGS) $<
$(OBJDIR)/mpv_sparcv9.o $(OBJDIR)/montmulfv9.o : $(OBJDIR)/%.o : %.s
@$(MAKE_OBJDIR)
$(SOLARIS_AS) -o $@ $(SOLARIS_AS_FLAGS) $<
$(OBJDIR)/mpmontg.o: mpmontg.c montmulf.h
endif
ifdef FREEBL_EXTENDED_BUILD
PURE32DIR = $(OBJDIR)/$(OS_TARGET)pure32
ALL_TRASH += $(PURE32DIR)
FILES2LN = \
$(wildcard *.tab) \
$(wildcard mapfile.*) \
Makefile manifest.mn config.mk
LINKEDFILES = $(addprefix $(PURE32DIR)/, $(FILES2LN))
CDDIR := $(shell pwd)
$(PURE32DIR):
-mkdir $(PURE32DIR)
-ln -s $(CDDIR)/mpi $(PURE32DIR)
$(LINKEDFILES) : $(PURE32DIR)/% : %
ln -s $(CDDIR)/$* $(PURE32DIR)
libs::
$(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_HYBRID=1 libs
libs:: $(PURE32DIR) $(LINKEDFILES)
cd $(PURE32DIR) && $(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_PURE_32=1 FREEBL_PARENT=$(CDDIR) CORE_DEPTH=$(CDDIR)/$(CORE_DEPTH) libs
release_md::
$(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_HYBRID=1 $@
cd $(PURE32DIR) && $(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_PURE_32=1 FREEBL_PARENT=$(CDDIR) CORE_DEPTH=$(CDDIR)/$(CORE_DEPTH) $@
endif

View File

@@ -1,383 +0,0 @@
/*
* aeskeywrap.c - implement AES Key Wrap algorithm from RFC 3394
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2002, 2003 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: aeskeywrap.c,v 1.1 2003-01-14 22:16:04 nelsonb%netscape.com Exp $
*/
#include "prcpucfg.h"
#if defined(IS_LITTLE_ENDIAN) || defined(SHA_NO_LONG_LONG)
#define BIG_ENDIAN_WITH_64_BIT_REGISTERS 0
#else
#define BIG_ENDIAN_WITH_64_BIT_REGISTERS 1
#endif
#include "prtypes.h" /* for PRUintXX */
#include "secport.h" /* for PORT_XXX */
#include "secerr.h"
#include "blapi.h" /* for AES_ functions */
struct AESKeyWrapContextStr {
AESContext * aescx;
unsigned char iv[AES_KEY_WRAP_IV_BYTES];
};
/******************************************/
/*
** AES key wrap algorithm, RFC 3394
*/
/*
** Create a new AES context suitable for AES encryption/decryption.
** "key" raw key data
** "keylen" the number of bytes of key data (16, 24, or 32)
*/
extern AESKeyWrapContext *
AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
int encrypt, unsigned int keylen)
{
AESKeyWrapContext * cx = PORT_ZNew(AESKeyWrapContext);
if (!cx)
return NULL; /* error is already set */
cx->aescx = AES_CreateContext(key, NULL, NSS_AES, encrypt, keylen,
AES_BLOCK_SIZE);
if (!cx->aescx) {
PORT_Free(cx);
return NULL; /* error should already be set */
}
if (iv) {
memcpy(cx->iv, iv, AES_KEY_WRAP_IV_BYTES);
} else {
memset(cx->iv, 0xA6, AES_KEY_WRAP_IV_BYTES);
}
return cx;
}
/*
** Destroy a AES KeyWrap context.
** "cx" the context
** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
extern void
AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
{
if (cx) {
if (cx->aescx)
AES_DestroyContext(cx->aescx, PR_TRUE);
memset(cx, 0, sizeof *cx);
if (freeit)
PORT_Free(cx);
}
}
#if !BIG_ENDIAN_WITH_64_BIT_REGISTERS
/* The AES Key Wrap algorithm has 64-bit values that are ALWAYS big-endian
** (Most significant byte first) in memory. The only ALU operations done
** on them are increment, decrement, and XOR. So, on little-endian CPUs,
** and on CPUs that lack 64-bit registers, these big-endian 64-bit operations
** are simulated in the following code. This is thought to be faster and
** simpler than trying to convert the data to little-endian and back.
*/
/* A and T point to two 64-bit values stored most signficant byte first
** (big endian). This function increments the 64-bit value T, and then
** XORs it with A, changing A.
*/
static void
increment_and_xor(unsigned char *A, unsigned char *T)
{
if (!++T[7])
if (!++T[6])
if (!++T[5])
if (!++T[4])
if (!++T[3])
if (!++T[2])
if (!++T[1])
++T[0];
A[0] ^= T[0];
A[1] ^= T[1];
A[2] ^= T[2];
A[3] ^= T[3];
A[4] ^= T[4];
A[5] ^= T[5];
A[6] ^= T[6];
A[7] ^= T[7];
}
/* A and T point to two 64-bit values stored most signficant byte first
** (big endian). This function XORs T with A, giving a new A, then
** decrements the 64-bit value T.
*/
static void
xor_and_decrement(unsigned char *A, unsigned char *T)
{
A[0] ^= T[0];
A[1] ^= T[1];
A[2] ^= T[2];
A[3] ^= T[3];
A[4] ^= T[4];
A[5] ^= T[5];
A[6] ^= T[6];
A[7] ^= T[7];
if (!T[7]--)
if (!T[6]--)
if (!T[5]--)
if (!T[4]--)
if (!T[3]--)
if (!T[2]--)
if (!T[1]--)
T[0]--;
}
/* Given an unsigned long t (in host byte order), store this value as a
** 64-bit big-endian value (MSB first) in *pt.
*/
static void
set_t(unsigned char *pt, unsigned long t)
{
pt[7] = (unsigned char)t; t >>= 8;
pt[6] = (unsigned char)t; t >>= 8;
pt[5] = (unsigned char)t; t >>= 8;
pt[4] = (unsigned char)t; t >>= 8;
pt[3] = (unsigned char)t; t >>= 8;
pt[2] = (unsigned char)t; t >>= 8;
pt[1] = (unsigned char)t; t >>= 8;
pt[0] = (unsigned char)t;
}
#endif
/*
** Perform AES key wrap.
** "cx" the context
** "output" the output buffer to store the encrypted data.
** "outputLen" how much data is stored in "output". Set by the routine
** after some data is stored in output.
** "maxOutputLen" the maximum amount of data that can ever be
** stored in "output"
** "input" the input data
** "inputLen" the amount of input data
*/
extern SECStatus
AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
unsigned int *pOutputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PRUint64 * R = NULL;
unsigned int nBlocks;
unsigned int i, j;
unsigned int aesLen = AES_BLOCK_SIZE;
unsigned int outLen = inputLen + AES_KEY_WRAP_BLOCK_SIZE;
SECStatus s = SECFailure;
/* These PRUint64s are ALWAYS big endian, regardless of CPU orientation. */
PRUint64 t;
PRUint64 B[2];
#define A B[0]
/* Check args */
if (!inputLen || 0 != inputLen % AES_KEY_WRAP_BLOCK_SIZE) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return s;
}
#ifdef maybe
if (!output && pOutputLen) { /* caller is asking for output size */
*pOutputLen = outLen;
return SECSuccess;
}
#endif
if (maxOutputLen < outLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return s;
}
if (cx == NULL || output == NULL || input == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return s;
}
nBlocks = inputLen / AES_KEY_WRAP_BLOCK_SIZE;
R = PORT_NewArray(PRUint64, nBlocks + 1);
if (!R)
return s; /* error is already set. */
/*
** 1) Initialize variables.
*/
memcpy(&A, cx->iv, AES_KEY_WRAP_IV_BYTES);
memcpy(&R[1], input, inputLen);
#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
t = 0;
#else
memset(&t, 0, sizeof t);
#endif
/*
** 2) Calculate intermediate values.
*/
for (j = 0; j < 6; ++j) {
for (i = 1; i <= nBlocks; ++i) {
B[1] = R[i];
s = AES_Encrypt(cx->aescx, (unsigned char *)B, &aesLen,
sizeof B, (unsigned char *)B, sizeof B);
if (s != SECSuccess)
break;
R[i] = B[1];
/* here, increment t and XOR A with t (in big endian order); */
#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
A ^= ++t;
#else
increment_and_xor((unsigned char *)&A, (unsigned char *)&t);
#endif
}
}
/*
** 3) Output the results.
*/
if (s == SECSuccess) {
R[0] = A;
memcpy(output, &R[0], outLen);
if (pOutputLen)
*pOutputLen = outLen;
} else if (pOutputLen) {
*pOutputLen = 0;
}
PORT_ZFree(R, outLen);
return s;
}
#undef A
/*
** Perform AES key unwrap.
** "cx" the context
** "output" the output buffer to store the decrypted data.
** "outputLen" how much data is stored in "output". Set by the routine
** after some data is stored in output.
** "maxOutputLen" the maximum amount of data that can ever be
** stored in "output"
** "input" the input data
** "inputLen" the amount of input data
*/
extern SECStatus
AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
unsigned int *pOutputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PRUint64 * R = NULL;
unsigned int nBlocks;
unsigned int i, j;
unsigned int aesLen = AES_BLOCK_SIZE;
unsigned int outLen;
SECStatus s = SECFailure;
/* These PRUint64s are ALWAYS big endian, regardless of CPU orientation. */
PRUint64 t;
PRUint64 B[2];
#define A B[0]
/* Check args */
if (inputLen < 3 * AES_KEY_WRAP_BLOCK_SIZE ||
0 != inputLen % AES_KEY_WRAP_BLOCK_SIZE) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return s;
}
outLen = inputLen - AES_KEY_WRAP_BLOCK_SIZE;
#ifdef maybe
if (!output && pOutputLen) { /* caller is asking for output size */
*pOutputLen = outLen;
return SECSuccess;
}
#endif
if (maxOutputLen < outLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return s;
}
if (cx == NULL || output == NULL || input == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return s;
}
nBlocks = inputLen / AES_KEY_WRAP_BLOCK_SIZE;
R = PORT_NewArray(PRUint64, nBlocks);
if (!R)
return s; /* error is already set. */
nBlocks--;
/*
** 1) Initialize variables.
*/
memcpy(&R[0], input, inputLen);
A = R[0];
#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
t = 6UL * nBlocks;
#else
set_t((unsigned char *)&t, 6UL * nBlocks);
#endif
/*
** 2) Calculate intermediate values.
*/
for (j = 0; j < 6; ++j) {
for (i = nBlocks; i; --i) {
/* here, XOR A with t (in big endian order) and decrement t; */
#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
A ^= t--;
#else
xor_and_decrement((unsigned char *)&A, (unsigned char *)&t);
#endif
B[1] = R[i];
s = AES_Decrypt(cx->aescx, (unsigned char *)B, &aesLen,
sizeof B, (unsigned char *)B, sizeof B);
if (s != SECSuccess)
break;
R[i] = B[1];
}
}
/*
** 3) Output the results.
*/
if (s == SECSuccess) {
int bad = memcmp(&A, cx->iv, AES_KEY_WRAP_IV_BYTES);
if (!bad) {
memcpy(output, &R[1], outLen);
if (pOutputLen)
*pOutputLen = outLen;
} else {
PORT_SetError(SEC_ERROR_BAD_DATA);
if (pOutputLen)
*pOutputLen = 0;
}
} else if (pOutputLen) {
*pOutputLen = 0;
}
PORT_ZFree(R, inputLen);
return s;
}
#undef A

View File

@@ -1,493 +0,0 @@
/*
* alg2268.c - implementation of the algorithm in RFC 2268
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: alg2268.c,v 1.4 2002-11-16 06:09:57 nelsonb%netscape.com Exp $
*/
#include "blapi.h"
#include "secerr.h"
#ifdef XP_UNIX_XXX
#include <stddef.h> /* for ptrdiff_t */
#endif
/*
** RC2 symmetric block cypher
*/
typedef SECStatus (rc2Func)(RC2Context *cx, unsigned char *output,
const unsigned char *input, unsigned int inputLen);
/* forward declarations */
static rc2Func rc2_EncryptECB;
static rc2Func rc2_DecryptECB;
static rc2Func rc2_EncryptCBC;
static rc2Func rc2_DecryptCBC;
typedef union {
PRUint32 l[2];
PRUint16 s[4];
PRUint8 b[8];
} RC2Block;
struct RC2ContextStr {
union {
PRUint8 Kb[128];
PRUint16 Kw[64];
} u;
RC2Block iv;
rc2Func *enc;
rc2Func *dec;
};
#define B u.Kb
#define K u.Kw
#define BYTESWAP(x) ((x) << 8 | (x) >> 8)
#define SWAPK(i) cx->K[i] = (tmpS = cx->K[i], BYTESWAP(tmpS))
#define RC2_BLOCK_SIZE 8
#define LOAD_HARD(R) \
R[0] = (PRUint16)input[1] << 8 | input[0]; \
R[1] = (PRUint16)input[3] << 8 | input[2]; \
R[2] = (PRUint16)input[5] << 8 | input[4]; \
R[3] = (PRUint16)input[7] << 8 | input[6];
#define LOAD_EASY(R) \
R[0] = ((PRUint16 *)input)[0]; \
R[1] = ((PRUint16 *)input)[1]; \
R[2] = ((PRUint16 *)input)[2]; \
R[3] = ((PRUint16 *)input)[3];
#define STORE_HARD(R) \
output[0] = (PRUint8)(R[0]); output[1] = (PRUint8)(R[0] >> 8); \
output[2] = (PRUint8)(R[1]); output[3] = (PRUint8)(R[1] >> 8); \
output[4] = (PRUint8)(R[2]); output[5] = (PRUint8)(R[2] >> 8); \
output[6] = (PRUint8)(R[3]); output[7] = (PRUint8)(R[3] >> 8);
#define STORE_EASY(R) \
((PRUint16 *)output)[0] = R[0]; \
((PRUint16 *)output)[1] = R[1]; \
((PRUint16 *)output)[2] = R[2]; \
((PRUint16 *)output)[3] = R[3];
#if defined (_X86_)
#define LOAD(R) LOAD_EASY(R)
#define STORE(R) STORE_EASY(R)
#elif !defined(IS_LITTLE_ENDIAN)
#define LOAD(R) LOAD_HARD(R)
#define STORE(R) STORE_HARD(R)
#else
#define LOAD(R) if ((ptrdiff_t)input & 1) { LOAD_HARD(R) } else { LOAD_EASY(R) }
#define STORE(R) if ((ptrdiff_t)input & 1) { STORE_HARD(R) } else { STORE_EASY(R) }
#endif
static const PRUint8 S[256] = {
0331,0170,0371,0304,0031,0335,0265,0355,0050,0351,0375,0171,0112,0240,0330,0235,
0306,0176,0067,0203,0053,0166,0123,0216,0142,0114,0144,0210,0104,0213,0373,0242,
0027,0232,0131,0365,0207,0263,0117,0023,0141,0105,0155,0215,0011,0201,0175,0062,
0275,0217,0100,0353,0206,0267,0173,0013,0360,0225,0041,0042,0134,0153,0116,0202,
0124,0326,0145,0223,0316,0140,0262,0034,0163,0126,0300,0024,0247,0214,0361,0334,
0022,0165,0312,0037,0073,0276,0344,0321,0102,0075,0324,0060,0243,0074,0266,0046,
0157,0277,0016,0332,0106,0151,0007,0127,0047,0362,0035,0233,0274,0224,0103,0003,
0370,0021,0307,0366,0220,0357,0076,0347,0006,0303,0325,0057,0310,0146,0036,0327,
0010,0350,0352,0336,0200,0122,0356,0367,0204,0252,0162,0254,0065,0115,0152,0052,
0226,0032,0322,0161,0132,0025,0111,0164,0113,0237,0320,0136,0004,0030,0244,0354,
0302,0340,0101,0156,0017,0121,0313,0314,0044,0221,0257,0120,0241,0364,0160,0071,
0231,0174,0072,0205,0043,0270,0264,0172,0374,0002,0066,0133,0045,0125,0227,0061,
0055,0135,0372,0230,0343,0212,0222,0256,0005,0337,0051,0020,0147,0154,0272,0311,
0323,0000,0346,0317,0341,0236,0250,0054,0143,0026,0001,0077,0130,0342,0211,0251,
0015,0070,0064,0033,0253,0063,0377,0260,0273,0110,0014,0137,0271,0261,0315,0056,
0305,0363,0333,0107,0345,0245,0234,0167,0012,0246,0040,0150,0376,0177,0301,0255
};
/*
** Create a new RC2 context suitable for RC2 encryption/decryption.
** "key" raw key data
** "len" the number of bytes of key data
** "iv" is the CBC initialization vector (if mode is NSS_RC2_CBC)
** "mode" one of NSS_RC2 or NSS_RC2_CBC
** "effectiveKeyLen" in bytes, not bits.
**
** When mode is set to NSS_RC2_CBC the RC2 cipher is run in "cipher block
** chaining" mode.
*/
RC2Context *
RC2_CreateContext(const unsigned char *key, unsigned int len,
const unsigned char *input, int mode, unsigned efLen8)
{
RC2Context *cx;
PRUint8 *L,*L2;
int i;
#if !defined(IS_LITTLE_ENDIAN)
PRUint16 tmpS;
#endif
PRUint8 tmpB;
if (!key || len == 0 || len > (sizeof cx->B) || efLen8 > (sizeof cx->B)) {
return NULL;
}
if (mode == NSS_RC2) {
/* groovy */
} else if (mode == NSS_RC2_CBC) {
if (!input) {
return NULL; /* not groovy */
}
} else {
return NULL;
}
cx = PORT_ZNew(RC2Context);
if (!cx)
return cx;
if (mode == NSS_RC2_CBC) {
cx->enc = & rc2_EncryptCBC;
cx->dec = & rc2_DecryptCBC;
LOAD(cx->iv.s);
} else {
cx->enc = & rc2_EncryptECB;
cx->dec = & rc2_DecryptECB;
}
/* Step 0. Copy key into table. */
memcpy(cx->B, key, len);
/* Step 1. Compute all values to the right of the key. */
L2 = cx->B;
L = L2 + len;
tmpB = L[-1];
for (i = (sizeof cx->B) - len; i > 0; --i) {
*L++ = tmpB = S[ (PRUint8)(tmpB + *L2++) ];
}
/* step 2. Adjust left most byte of effective key. */
i = (sizeof cx->B) - efLen8;
L = cx->B + i;
*L = tmpB = S[*L]; /* mask is always 0xff */
/* step 3. Recompute all values to the left of effective key. */
L2 = --L + efLen8;
while(L >= cx->B) {
*L-- = tmpB = S[ tmpB ^ *L2-- ];
}
#if !defined(IS_LITTLE_ENDIAN)
for (i = 63; i >= 0; --i) {
SWAPK(i); /* candidate for unrolling */
}
#endif
return cx;
}
/*
** Destroy an RC2 encryption/decryption context.
** "cx" the context
** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
void
RC2_DestroyContext(RC2Context *cx, PRBool freeit)
{
if (cx) {
memset(cx, 0, sizeof *cx);
if (freeit) {
PORT_Free(cx);
}
}
}
#define ROL(x,k) (x << k | x >> (16-k))
#define MIX(j) \
R0 = R0 + cx->K[ 4*j+0] + (R3 & R2) + (~R3 & R1); R0 = ROL(R0,1);\
R1 = R1 + cx->K[ 4*j+1] + (R0 & R3) + (~R0 & R2); R1 = ROL(R1,2);\
R2 = R2 + cx->K[ 4*j+2] + (R1 & R0) + (~R1 & R3); R2 = ROL(R2,3);\
R3 = R3 + cx->K[ 4*j+3] + (R2 & R1) + (~R2 & R0); R3 = ROL(R3,5)
#define MASH \
R0 = R0 + cx->K[R3 & 63];\
R1 = R1 + cx->K[R0 & 63];\
R2 = R2 + cx->K[R1 & 63];\
R3 = R3 + cx->K[R2 & 63]
/* Encrypt one block */
static void
rc2_Encrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
{
register PRUint16 R0, R1, R2, R3;
/* step 1. Initialize input. */
R0 = input->s[0];
R1 = input->s[1];
R2 = input->s[2];
R3 = input->s[3];
/* step 2. Expand Key (already done, in context) */
/* step 3. j = 0 */
/* step 4. Perform 5 mixing rounds. */
MIX(0);
MIX(1);
MIX(2);
MIX(3);
MIX(4);
/* step 5. Perform 1 mashing round. */
MASH;
/* step 6. Perform 6 mixing rounds. */
MIX(5);
MIX(6);
MIX(7);
MIX(8);
MIX(9);
MIX(10);
/* step 7. Perform 1 mashing round. */
MASH;
/* step 8. Perform 5 mixing rounds. */
MIX(11);
MIX(12);
MIX(13);
MIX(14);
MIX(15);
/* output results */
output->s[0] = R0;
output->s[1] = R1;
output->s[2] = R2;
output->s[3] = R3;
}
#define ROR(x,k) (x >> k | x << (16-k))
#define R_MIX(j) \
R3 = ROR(R3,5); R3 = R3 - cx->K[ 4*j+3] - (R2 & R1) - (~R2 & R0); \
R2 = ROR(R2,3); R2 = R2 - cx->K[ 4*j+2] - (R1 & R0) - (~R1 & R3); \
R1 = ROR(R1,2); R1 = R1 - cx->K[ 4*j+1] - (R0 & R3) - (~R0 & R2); \
R0 = ROR(R0,1); R0 = R0 - cx->K[ 4*j+0] - (R3 & R2) - (~R3 & R1)
#define R_MASH \
R3 = R3 - cx->K[R2 & 63];\
R2 = R2 - cx->K[R1 & 63];\
R1 = R1 - cx->K[R0 & 63];\
R0 = R0 - cx->K[R3 & 63]
/* Encrypt one block */
static void
rc2_Decrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
{
register PRUint16 R0, R1, R2, R3;
/* step 1. Initialize input. */
R0 = input->s[0];
R1 = input->s[1];
R2 = input->s[2];
R3 = input->s[3];
/* step 2. Expand Key (already done, in context) */
/* step 3. j = 63 */
/* step 4. Perform 5 r_mixing rounds. */
R_MIX(15);
R_MIX(14);
R_MIX(13);
R_MIX(12);
R_MIX(11);
/* step 5. Perform 1 r_mashing round. */
R_MASH;
/* step 6. Perform 6 r_mixing rounds. */
R_MIX(10);
R_MIX(9);
R_MIX(8);
R_MIX(7);
R_MIX(6);
R_MIX(5);
/* step 7. Perform 1 r_mashing round. */
R_MASH;
/* step 8. Perform 5 r_mixing rounds. */
R_MIX(4);
R_MIX(3);
R_MIX(2);
R_MIX(1);
R_MIX(0);
/* output results */
output->s[0] = R0;
output->s[1] = R1;
output->s[2] = R2;
output->s[3] = R3;
}
static SECStatus
rc2_EncryptECB(RC2Context *cx, unsigned char *output,
const unsigned char *input, unsigned int inputLen)
{
RC2Block iBlock;
while (inputLen > 0) {
LOAD(iBlock.s)
rc2_Encrypt1Block(cx, &iBlock, &iBlock);
STORE(iBlock.s)
output += RC2_BLOCK_SIZE;
input += RC2_BLOCK_SIZE;
inputLen -= RC2_BLOCK_SIZE;
}
return SECSuccess;
}
static SECStatus
rc2_DecryptECB(RC2Context *cx, unsigned char *output,
const unsigned char *input, unsigned int inputLen)
{
RC2Block iBlock;
while (inputLen > 0) {
LOAD(iBlock.s)
rc2_Decrypt1Block(cx, &iBlock, &iBlock);
STORE(iBlock.s)
output += RC2_BLOCK_SIZE;
input += RC2_BLOCK_SIZE;
inputLen -= RC2_BLOCK_SIZE;
}
return SECSuccess;
}
static SECStatus
rc2_EncryptCBC(RC2Context *cx, unsigned char *output,
const unsigned char *input, unsigned int inputLen)
{
RC2Block iBlock;
while (inputLen > 0) {
LOAD(iBlock.s)
iBlock.l[0] ^= cx->iv.l[0];
iBlock.l[1] ^= cx->iv.l[1];
rc2_Encrypt1Block(cx, &iBlock, &iBlock);
cx->iv = iBlock;
STORE(iBlock.s)
output += RC2_BLOCK_SIZE;
input += RC2_BLOCK_SIZE;
inputLen -= RC2_BLOCK_SIZE;
}
return SECSuccess;
}
static SECStatus
rc2_DecryptCBC(RC2Context *cx, unsigned char *output,
const unsigned char *input, unsigned int inputLen)
{
RC2Block iBlock;
RC2Block oBlock;
while (inputLen > 0) {
LOAD(iBlock.s)
rc2_Decrypt1Block(cx, &oBlock, &iBlock);
oBlock.l[0] ^= cx->iv.l[0];
oBlock.l[1] ^= cx->iv.l[1];
cx->iv = iBlock;
STORE(oBlock.s)
output += RC2_BLOCK_SIZE;
input += RC2_BLOCK_SIZE;
inputLen -= RC2_BLOCK_SIZE;
}
return SECSuccess;
}
/*
** Perform RC2 encryption.
** "cx" the context
** "output" the output buffer to store the encrypted data.
** "outputLen" how much data is stored in "output". Set by the routine
** after some data is stored in output.
** "maxOutputLen" the maximum amount of data that can ever be
** stored in "output"
** "input" the input data
** "inputLen" the amount of input data
*/
SECStatus RC2_Encrypt(RC2Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
SECStatus rv = SECSuccess;
if (inputLen) {
if (inputLen % RC2_BLOCK_SIZE) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure;
}
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
rv = (*cx->enc)(cx, output, input, inputLen);
}
if (rv == SECSuccess) {
*outputLen = inputLen;
}
return rv;
}
/*
** Perform RC2 decryption.
** "cx" the context
** "output" the output buffer to store the decrypted data.
** "outputLen" how much data is stored in "output". Set by the routine
** after some data is stored in output.
** "maxOutputLen" the maximum amount of data that can ever be
** stored in "output"
** "input" the input data
** "inputLen" the amount of input data
*/
SECStatus RC2_Decrypt(RC2Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
SECStatus rv = SECSuccess;
if (inputLen) {
if (inputLen % RC2_BLOCK_SIZE) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure;
}
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
rv = (*cx->dec)(cx, output, input, inputLen);
}
if (rv == SECSuccess) {
*outputLen = inputLen;
}
return rv;
}

View File

@@ -1,114 +0,0 @@
/*
* arcfive.c - stubs for RC5 - NOT a working implementation!
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: arcfive.c,v 1.3 2002-11-16 06:09:57 nelsonb%netscape.com Exp $
*/
#include "blapi.h"
#include "prerror.h"
/******************************************/
/*
** RC5 symmetric block cypher -- 64-bit block size
*/
/*
** Create a new RC5 context suitable for RC5 encryption/decryption.
** "key" raw key data
** "len" the number of bytes of key data
** "iv" is the CBC initialization vector (if mode is NSS_RC5_CBC)
** "mode" one of NSS_RC5 or NSS_RC5_CBC
**
** When mode is set to NSS_RC5_CBC the RC5 cipher is run in "cipher block
** chaining" mode.
*/
RC5Context *
RC5_CreateContext(const SECItem *key, unsigned int rounds,
unsigned int wordSize, const unsigned char *iv, int mode)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return NULL;
}
/*
** Destroy an RC5 encryption/decryption context.
** "cx" the context
** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
void
RC5_DestroyContext(RC5Context *cx, PRBool freeit)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
}
/*
** Perform RC5 encryption.
** "cx" the context
** "output" the output buffer to store the encrypted data.
** "outputLen" how much data is stored in "output". Set by the routine
** after some data is stored in output.
** "maxOutputLen" the maximum amount of data that can ever be
** stored in "output"
** "input" the input data
** "inputLen" the amount of input data
*/
SECStatus
RC5_Encrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
}
/*
** Perform RC5 decryption.
** "cx" the context
** "output" the output buffer to store the decrypted data.
** "outputLen" how much data is stored in "output". Set by the routine
** after some data is stored in output.
** "maxOutputLen" the maximum amount of data that can ever be
** stored in "output"
** "input" the input data
** "inputLen" the amount of input data
*/
SECStatus
RC5_Decrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
}

View File

@@ -1,567 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "prerr.h"
#include "secerr.h"
#include "prtypes.h"
#include "blapi.h"
/* Architecture-dependent defines */
#if defined(SOLARIS) || defined(HPUX) || defined(i386) || defined(IRIX)
/* Convert the byte-stream to a word-stream */
#define CONVERT_TO_WORDS
#endif
#if defined(AIX) || defined(OSF1)
/* Treat array variables as longs, not bytes */
#define USE_LONG
#endif
#if defined(_WIN32_WCE)
#undef WORD
#define WORD ARC4WORD
#endif
#if defined(NSS_USE_HYBRID) && !defined(SOLARIS) && !defined(NSS_USE_64)
typedef unsigned long long WORD;
#else
typedef unsigned long WORD;
#endif
#define WORDSIZE sizeof(WORD)
#ifdef USE_LONG
typedef unsigned long Stype;
#else
typedef PRUint8 Stype;
#endif
#define ARCFOUR_STATE_SIZE 256
#define MASK1BYTE (WORD)(0xff)
#define SWAP(a, b) \
tmp = a; \
a = b; \
b = tmp;
/*
* State information for stream cipher.
*/
struct RC4ContextStr
{
Stype S[ARCFOUR_STATE_SIZE];
PRUint8 i;
PRUint8 j;
};
/*
* array indices [0..255] to initialize cx->S array (faster than loop).
*/
static const Stype Kinit[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
/*
* Initialize a new generator.
*/
RC4Context *
RC4_CreateContext(const unsigned char *key, int len)
{
int i;
PRUint8 j, tmp;
RC4Context *cx;
PRUint8 K[256];
PRUint8 *L;
/* verify the key length. */
PORT_Assert(len > 0 && len < ARCFOUR_STATE_SIZE);
if (len < 0 || len >= ARCFOUR_STATE_SIZE) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
/* Create space for the context. */
cx = (RC4Context *)PORT_ZAlloc(sizeof(RC4Context));
if (cx == NULL) {
PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
return NULL;
}
/* Initialize the state using array indices. */
memcpy(cx->S, Kinit, sizeof cx->S);
/* Fill in K repeatedly with values from key. */
L = K;
for (i = sizeof K; i > len; i-= len) {
memcpy(L, key, len);
L += len;
}
memcpy(L, key, i);
/* Stir the state of the generator. At this point it is assumed
* that the key is the size of the state buffer. If this is not
* the case, the key bytes are repeated to fill the buffer.
*/
j = 0;
#define ARCFOUR_STATE_STIR(ii) \
j = j + cx->S[ii] + K[ii]; \
SWAP(cx->S[ii], cx->S[j]);
for (i=0; i<ARCFOUR_STATE_SIZE; i++) {
ARCFOUR_STATE_STIR(i);
}
cx->i = 0;
cx->j = 0;
return cx;
}
void
RC4_DestroyContext(RC4Context *cx, PRBool freeit)
{
if (freeit)
PORT_ZFree(cx, sizeof(*cx));
}
/*
* Generate the next byte in the stream.
*/
#define ARCFOUR_NEXT_BYTE() \
tmpSi = cx->S[++tmpi]; \
tmpj += tmpSi; \
tmpSj = cx->S[tmpj]; \
cx->S[tmpi] = tmpSj; \
cx->S[tmpj] = tmpSi; \
t = tmpSi + tmpSj;
#ifdef CONVERT_TO_WORDS
/*
* Straight RC4 op. No optimization.
*/
static SECStatus
rc4_no_opt(RC4Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PRUint8 t;
Stype tmpSi, tmpSj;
register PRUint8 tmpi = cx->i;
register PRUint8 tmpj = cx->j;
unsigned int index;
PORT_Assert(maxOutputLen >= inputLen);
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
for (index=0; index < inputLen; index++) {
/* Generate next byte from stream. */
ARCFOUR_NEXT_BYTE();
/* output = next stream byte XOR next input byte */
output[index] = cx->S[t] ^ input[index];
}
*outputLen = inputLen;
cx->i = tmpi;
cx->j = tmpj;
return SECSuccess;
}
#endif
#ifndef CONVERT_TO_WORDS
/*
* Byte-at-a-time RC4, unrolling the loop into 8 pieces.
*/
static SECStatus
rc4_unrolled(RC4Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PRUint8 t;
Stype tmpSi, tmpSj;
register PRUint8 tmpi = cx->i;
register PRUint8 tmpj = cx->j;
int index;
PORT_Assert(maxOutputLen >= inputLen);
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
for (index = inputLen / 8; index-- > 0; input += 8, output += 8) {
ARCFOUR_NEXT_BYTE();
output[0] = cx->S[t] ^ input[0];
ARCFOUR_NEXT_BYTE();
output[1] = cx->S[t] ^ input[1];
ARCFOUR_NEXT_BYTE();
output[2] = cx->S[t] ^ input[2];
ARCFOUR_NEXT_BYTE();
output[3] = cx->S[t] ^ input[3];
ARCFOUR_NEXT_BYTE();
output[4] = cx->S[t] ^ input[4];
ARCFOUR_NEXT_BYTE();
output[5] = cx->S[t] ^ input[5];
ARCFOUR_NEXT_BYTE();
output[6] = cx->S[t] ^ input[6];
ARCFOUR_NEXT_BYTE();
output[7] = cx->S[t] ^ input[7];
}
index = inputLen % 8;
if (index) {
input += index;
output += index;
switch (index) {
case 7:
ARCFOUR_NEXT_BYTE();
output[-7] = cx->S[t] ^ input[-7]; /* FALLTHRU */
case 6:
ARCFOUR_NEXT_BYTE();
output[-6] = cx->S[t] ^ input[-6]; /* FALLTHRU */
case 5:
ARCFOUR_NEXT_BYTE();
output[-5] = cx->S[t] ^ input[-5]; /* FALLTHRU */
case 4:
ARCFOUR_NEXT_BYTE();
output[-4] = cx->S[t] ^ input[-4]; /* FALLTHRU */
case 3:
ARCFOUR_NEXT_BYTE();
output[-3] = cx->S[t] ^ input[-3]; /* FALLTHRU */
case 2:
ARCFOUR_NEXT_BYTE();
output[-2] = cx->S[t] ^ input[-2]; /* FALLTHRU */
case 1:
ARCFOUR_NEXT_BYTE();
output[-1] = cx->S[t] ^ input[-1]; /* FALLTHRU */
default:
/* FALLTHRU */
; /* hp-ux build breaks without this */
}
}
cx->i = tmpi;
cx->j = tmpj;
*outputLen = inputLen;
return SECSuccess;
}
#endif
#ifdef IS_LITTLE_ENDIAN
#define ARCFOUR_NEXT4BYTES_L(n) \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n ); \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 8); \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 16); \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 24);
#else
#define ARCFOUR_NEXT4BYTES_B(n) \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 24); \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 16); \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 8); \
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n );
#endif
#if (defined(NSS_USE_HYBRID) && !defined(SOLARIS)) || defined(NSS_USE_64)
/* 64-bit wordsize */
#ifdef IS_LITTLE_ENDIAN
#define ARCFOUR_NEXT_WORD() \
{ streamWord = 0; ARCFOUR_NEXT4BYTES_L(0); ARCFOUR_NEXT4BYTES_L(32); }
#else
#define ARCFOUR_NEXT_WORD() \
{ streamWord = 0; ARCFOUR_NEXT4BYTES_B(32); ARCFOUR_NEXT4BYTES_B(0); }
#endif
#else
/* 32-bit wordsize */
#ifdef IS_LITTLE_ENDIAN
#define ARCFOUR_NEXT_WORD() \
{ streamWord = 0; ARCFOUR_NEXT4BYTES_L(0); }
#else
#define ARCFOUR_NEXT_WORD() \
{ streamWord = 0; ARCFOUR_NEXT4BYTES_B(0); }
#endif
#endif
#ifdef IS_LITTLE_ENDIAN
#define RSH <<
#define LSH >>
#else
#define RSH >>
#define LSH <<
#endif
#ifdef CONVERT_TO_WORDS
/*
* Convert input and output buffers to words before performing
* RC4 operations.
*/
static SECStatus
rc4_wordconv(RC4Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
ptrdiff_t inOffset = (ptrdiff_t)input % WORDSIZE;
ptrdiff_t outOffset = (ptrdiff_t)output % WORDSIZE;
register WORD streamWord, mask;
register WORD *pInWord, *pOutWord;
register WORD inWord, nextInWord;
PRUint8 t;
register Stype tmpSi, tmpSj;
register PRUint8 tmpi = cx->i;
register PRUint8 tmpj = cx->j;
unsigned int byteCount;
unsigned int bufShift, invBufShift;
int i;
PORT_Assert(maxOutputLen >= inputLen);
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (inputLen < 2*WORDSIZE) {
/* Ignore word conversion, do byte-at-a-time */
return rc4_no_opt(cx, output, outputLen, maxOutputLen, input, inputLen);
}
*outputLen = inputLen;
pInWord = (WORD *)(input - inOffset);
if (inOffset < outOffset) {
bufShift = 8*(outOffset - inOffset);
invBufShift = 8*WORDSIZE - bufShift;
} else {
invBufShift = 8*(inOffset - outOffset);
bufShift = 8*WORDSIZE - invBufShift;
}
/*****************************************************************/
/* Step 1: */
/* If the first output word is partial, consume the bytes in the */
/* first partial output word by loading one or two words of */
/* input and shifting them accordingly. Otherwise, just load */
/* in the first word of input. At the end of this block, at */
/* least one partial word of input should ALWAYS be loaded. */
/*****************************************************************/
if (outOffset) {
/* Generate input and stream words aligned relative to the
* partial output buffer.
*/
byteCount = WORDSIZE - outOffset;
pOutWord = (WORD *)(output - outOffset);
mask = streamWord = 0;
#ifdef IS_LITTLE_ENDIAN
for (i = WORDSIZE - byteCount; i < WORDSIZE; i++) {
#else
for (i = byteCount - 1; i >= 0; --i) {
#endif
ARCFOUR_NEXT_BYTE();
streamWord |= (WORD)(cx->S[t]) << 8*i;
mask |= MASK1BYTE << 8*i;
} /* } */
inWord = *pInWord++;
/* If buffers are relatively misaligned, shift the bytes in inWord
* to be aligned to the output buffer.
*/
nextInWord = 0;
if (inOffset < outOffset) {
/* Have more bytes than needed, shift remainder into nextInWord */
nextInWord = inWord LSH 8*(inOffset + byteCount);
inWord = inWord RSH bufShift;
} else if (inOffset > outOffset) {
/* Didn't get enough bytes from current input word, load another
* word and then shift remainder into nextInWord.
*/
nextInWord = *pInWord++;
inWord = (inWord LSH invBufShift) |
(nextInWord RSH bufShift);
nextInWord = nextInWord LSH invBufShift;
}
/* Store output of first partial word */
*pOutWord = (*pOutWord & ~mask) | ((inWord ^ streamWord) & mask);
/* Consumed byteCount bytes of input */
inputLen -= byteCount;
/* move to next word of output */
pOutWord++;
/* inWord has been consumed, but there may be bytes in nextInWord */
inWord = nextInWord;
} else {
/* output is word-aligned */
pOutWord = (WORD *)output;
if (inOffset) {
/* Input is not word-aligned. The first word load of input
* will not produce a full word of input bytes, so one word
* must be pre-loaded. The main loop below will load in the
* next input word and shift some of its bytes into inWord
* in order to create a full input word. Note that the main
* loop must execute at least once because the input must
* be at least two words.
*/
inWord = *pInWord++;
inWord = inWord LSH invBufShift;
} else {
/* Input is word-aligned. The first word load of input
* will produce a full word of input bytes, so nothing
* needs to be loaded here.
*/
inWord = 0;
}
}
/* Output buffer is aligned, inOffset is now measured relative to
* outOffset (and not a word boundary).
*/
inOffset = (inOffset + WORDSIZE - outOffset) % WORDSIZE;
/*****************************************************************/
/* Step 2: main loop */
/* At this point the output buffer is word-aligned. Any unused */
/* bytes from above will be in inWord (shifted correctly). If */
/* the input buffer is unaligned relative to the output buffer, */
/* shifting has to be done. */
/*****************************************************************/
if (inOffset) {
for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) {
nextInWord = *pInWord++;
inWord |= nextInWord RSH bufShift;
nextInWord = nextInWord LSH invBufShift;
ARCFOUR_NEXT_WORD();
*pOutWord++ = inWord ^ streamWord;
inWord = nextInWord;
}
if (inputLen == 0) {
/* Nothing left to do. */
cx->i = tmpi;
cx->j = tmpj;
return SECSuccess;
}
/* If the amount of remaining input is greater than the amount
* bytes pulled from the current input word, need to do another
* word load. What's left in inWord will be consumed in step 3.
*/
if (inputLen > WORDSIZE - inOffset)
inWord |= *pInWord RSH bufShift;
} else {
for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) {
inWord = *pInWord++;
ARCFOUR_NEXT_WORD();
*pOutWord++ = inWord ^ streamWord;
}
if (inputLen == 0) {
/* Nothing left to do. */
cx->i = tmpi;
cx->j = tmpj;
return SECSuccess;
} else {
/* A partial input word remains at the tail. Load it. The
* relevant bytes will be consumed in step 3.
*/
inWord = *pInWord;
}
}
/*****************************************************************/
/* Step 3: */
/* A partial word of input remains, and it is already loaded */
/* into nextInWord. Shift appropriately and consume the bytes */
/* used in the partial word. */
/*****************************************************************/
mask = streamWord = 0;
#ifdef IS_LITTLE_ENDIAN
for (i = 0; i < inputLen; ++i) {
#else
for (i = WORDSIZE - 1; i >= WORDSIZE - inputLen; --i) {
#endif
ARCFOUR_NEXT_BYTE();
streamWord |= (WORD)(cx->S[t]) << 8*i;
mask |= MASK1BYTE << 8*i;
} /* } */
*pOutWord = (*pOutWord & ~mask) | ((inWord ^ streamWord) & mask);
cx->i = tmpi;
cx->j = tmpj;
return SECSuccess;
}
#endif
SECStatus
RC4_Encrypt(RC4Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PORT_Assert(maxOutputLen >= inputLen);
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
#ifdef CONVERT_TO_WORDS
/* Convert the byte-stream to a word-stream */
return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen);
#else
/* Operate on bytes, but unroll the main loop */
return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen);
#endif
}
SECStatus RC4_Decrypt(RC4Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PORT_Assert(maxOutputLen >= inputLen);
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* decrypt and encrypt are same operation. */
#ifdef CONVERT_TO_WORDS
/* Convert the byte-stream to a word-stream */
return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen);
#else
/* Operate on bytes, but unroll the main loop */
return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen);
#endif
}
#undef CONVERT_TO_WORDS
#undef USE_LONG

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,336 +0,0 @@
/*
* blapit.h - public data structures for the crypto library
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: blapit.h,v 1.10 2003-03-29 00:18:18 nelsonb%netscape.com Exp $
*/
#ifndef _BLAPIT_H_
#define _BLAPIT_H_
#include "seccomon.h"
#include "prlink.h"
#include "plarena.h"
/* RC2 operation modes */
#define NSS_RC2 0
#define NSS_RC2_CBC 1
/* RC5 operation modes */
#define NSS_RC5 0
#define NSS_RC5_CBC 1
/* DES operation modes */
#define NSS_DES 0
#define NSS_DES_CBC 1
#define NSS_DES_EDE3 2
#define NSS_DES_EDE3_CBC 3
#define DES_KEY_LENGTH 8 /* Bytes */
/* AES operation modes */
#define NSS_AES 0
#define NSS_AES_CBC 1
#define DSA_SIGNATURE_LEN 40 /* Bytes */
#define DSA_SUBPRIME_LEN 20 /* Bytes */
/* XXX We shouldn't have to hard code this limit. For
* now, this is the quickest way to support ECDSA signature
* processing (ECDSA signature lengths depend on curve
* size). This limit is sufficient for curves upto
* 576 bits.
*/
#define MAX_ECKEY_LEN 72 /* Bytes */
/*
* Number of bytes each hash algorithm produces
*/
#define MD2_LENGTH 16 /* Bytes */
#define MD5_LENGTH 16 /* Bytes */
#define SHA1_LENGTH 20 /* Bytes */
#define SHA256_LENGTH 32 /* bytes */
#define SHA384_LENGTH 48 /* bytes */
#define SHA512_LENGTH 64 /* bytes */
#define HASH_LENGTH_MAX SHA512_LENGTH
/*
* Input block size for each hash algorithm.
*/
#define SHA256_BLOCK_LENGTH 64 /* bytes */
#define SHA384_BLOCK_LENGTH 128 /* bytes */
#define SHA512_BLOCK_LENGTH 128 /* bytes */
#define AES_KEY_WRAP_IV_BYTES 8
#define AES_KEY_WRAP_BLOCK_SIZE 8 /* bytes */
#define AES_BLOCK_SIZE 16 /* bytes */
#define NSS_FREEBL_DEFAULT_CHUNKSIZE 2048
/*
* The FIPS 186 algorithm for generating primes P and Q allows only 9
* distinct values for the length of P, and only one value for the
* length of Q.
* The algorithm uses a variable j to indicate which of the 9 lengths
* of P is to be used.
* The following table relates j to the lengths of P and Q in bits.
*
* j bits in P bits in Q
* _ _________ _________
* 0 512 160
* 1 576 160
* 2 640 160
* 3 704 160
* 4 768 160
* 5 832 160
* 6 896 160
* 7 960 160
* 8 1024 160
*
* The FIPS-186 compliant PQG generator takes j as an input parameter.
*/
#define DSA_Q_BITS 160
#define DSA_MAX_P_BITS 1024
#define DSA_MIN_P_BITS 512
/*
* function takes desired number of bits in P,
* returns index (0..8) or -1 if number of bits is invalid.
*/
#define PQG_PBITS_TO_INDEX(bits) ((((bits)-512) % 64) ? -1 : (int)((bits)-512)/64)
/*
* function takes index (0-8)
* returns number of bits in P for that index, or -1 if index is invalid.
*/
#define PQG_INDEX_TO_PBITS(j) (((unsigned)(j) > 8) ? -1 : (512 + 64 * (j)))
/***************************************************************************
** Opaque objects
*/
struct DESContextStr ;
struct RC2ContextStr ;
struct RC4ContextStr ;
struct RC5ContextStr ;
struct AESContextStr ;
struct MD2ContextStr ;
struct MD5ContextStr ;
struct SHA1ContextStr ;
struct SHA256ContextStr ;
struct SHA512ContextStr ;
struct AESKeyWrapContextStr ;
typedef struct DESContextStr DESContext;
typedef struct RC2ContextStr RC2Context;
typedef struct RC4ContextStr RC4Context;
typedef struct RC5ContextStr RC5Context;
typedef struct AESContextStr AESContext;
typedef struct MD2ContextStr MD2Context;
typedef struct MD5ContextStr MD5Context;
typedef struct SHA1ContextStr SHA1Context;
typedef struct SHA256ContextStr SHA256Context;
typedef struct SHA512ContextStr SHA512Context;
/* SHA384Context is really a SHA512ContextStr. This is not a mistake. */
typedef struct SHA512ContextStr SHA384Context;
typedef struct AESKeyWrapContextStr AESKeyWrapContext;
/***************************************************************************
** RSA Public and Private Key structures
*/
/* member names from PKCS#1, section 7.1 */
struct RSAPublicKeyStr {
PRArenaPool * arena;
SECItem modulus;
SECItem publicExponent;
};
typedef struct RSAPublicKeyStr RSAPublicKey;
/* member names from PKCS#1, section 7.2 */
struct RSAPrivateKeyStr {
PRArenaPool * arena;
SECItem version;
SECItem modulus;
SECItem publicExponent;
SECItem privateExponent;
SECItem prime1;
SECItem prime2;
SECItem exponent1;
SECItem exponent2;
SECItem coefficient;
};
typedef struct RSAPrivateKeyStr RSAPrivateKey;
/***************************************************************************
** DSA Public and Private Key and related structures
*/
struct PQGParamsStr {
PRArenaPool *arena;
SECItem prime; /* p */
SECItem subPrime; /* q */
SECItem base; /* g */
/* XXX chrisk: this needs to be expanded to hold j and validationParms (RFC2459 7.3.2) */
};
typedef struct PQGParamsStr PQGParams;
struct PQGVerifyStr {
PRArenaPool * arena; /* includes this struct, seed, & h. */
unsigned int counter;
SECItem seed;
SECItem h;
};
typedef struct PQGVerifyStr PQGVerify;
struct DSAPublicKeyStr {
PQGParams params;
SECItem publicValue;
};
typedef struct DSAPublicKeyStr DSAPublicKey;
struct DSAPrivateKeyStr {
PQGParams params;
SECItem publicValue;
SECItem privateValue;
};
typedef struct DSAPrivateKeyStr DSAPrivateKey;
/***************************************************************************
** Diffie-Hellman Public and Private Key and related structures
** Structure member names suggested by PKCS#3.
*/
struct DHParamsStr {
PRArenaPool * arena;
SECItem prime; /* p */
SECItem base; /* g */
};
typedef struct DHParamsStr DHParams;
struct DHPublicKeyStr {
PRArenaPool * arena;
SECItem prime;
SECItem base;
SECItem publicValue;
};
typedef struct DHPublicKeyStr DHPublicKey;
struct DHPrivateKeyStr {
PRArenaPool * arena;
SECItem prime;
SECItem base;
SECItem publicValue;
SECItem privateValue;
};
typedef struct DHPrivateKeyStr DHPrivateKey;
/***************************************************************************
** Data structures used for elliptic curve parameters and
** public and private keys.
*/
/*
** The ECParams data structures can encode elliptic curve
** parameters for both GFp and GF2m curves.
*/
typedef enum { ec_params_explicit,
ec_params_named
} ECParamsType;
typedef enum { ec_field_GFp = 1,
ec_field_GF2m
} ECFieldType;
struct ECFieldIDStr {
int size; /* field size in bits */
ECFieldType type;
union {
SECItem prime; /* prime p for (GFp) */
SECItem poly; /* irreducible binary polynomial for (GF2m) */
} u;
int k1; /* first coefficient of pentanomial or
* the only coefficient of trinomial
*/
int k2; /* two remaining coefficients of pentanomial */
int k3;
};
typedef struct ECFieldIDStr ECFieldID;
struct ECCurveStr {
SECItem a; /* contains octet stream encoding of
* field element (X9.62 section 4.3.3)
*/
SECItem b;
SECItem seed;
};
typedef struct ECCurveStr ECCurve;
struct ECParamsStr {
PRArenaPool * arena;
ECParamsType type;
ECFieldID fieldID;
ECCurve curve;
SECItem base;
SECItem order;
int cofactor;
SECItem DEREncoding;
};
typedef struct ECParamsStr ECParams;
struct ECPublicKeyStr {
ECParams ecParams;
SECItem publicValue; /* elliptic curve point encoded as
* octet stream.
*/
};
typedef struct ECPublicKeyStr ECPublicKey;
struct ECPrivateKeyStr {
ECParams ecParams;
SECItem publicValue; /* encoded ec point */
SECItem privateValue; /* private big integer */
};
typedef struct ECPrivateKeyStr ECPrivateKey;
#endif /* _BLAPIT_H_ */

View File

@@ -1,103 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
# only do this in the outermost freebl build.
ifndef FREEBL_RECURSIVE_BUILD
# we only do this stuff for some of the 32-bit builds, no 64-bit builds
ifndef USE_64
ifeq ($(OS_TARGET), HP-UX)
ifneq ($(OS_TEST), ia64)
FREEBL_EXTENDED_BUILD = 1
endif
endif
ifeq ($(OS_TARGET),SunOS)
ifeq ($(CPU_ARCH),sparc)
FREEBL_EXTENDED_BUILD = 1
endif
endif
ifdef FREEBL_EXTENDED_BUILD
# We're going to change this build so that it builds libfreebl.a with
# just loader.c. Then we have to build this directory twice again to
# build the two DSOs.
# To build libfreebl.a with just loader.c, we must now override many
# of the make variables setup by the prior inclusion of CORECONF's config.mk
CSRCS = loader.c sysrand.c
SIMPLE_OBJS = $(CSRCS:.c=$(OBJ_SUFFIX))
OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(SIMPLE_OBJS))
ALL_TRASH := $(TARGETS) $(OBJS) $(OBJDIR) LOGS TAGS $(GARBAGE) \
$(NOSUCHFILE) so_locations
endif
#end of 32-bit only stuff.
endif
# Override the values defined in coreconf's ruleset.mk.
#
# - (1) LIBRARY: a static (archival) library
# - (2) SHARED_LIBRARY: a shared (dynamic link) library
# - (3) IMPORT_LIBRARY: an import library, used only on Windows
# - (4) PROGRAM: an executable binary
#
# override these variables to prevent building a DSO/DLL.
TARGETS = $(LIBRARY)
SHARED_LIBRARY =
IMPORT_LIBRARY =
PROGRAM =
else
# This is a recursive build.
TARGETS = $(SHARED_LIBRARY)
LIBRARY =
PROGRAM =
#ifeq ($(OS_TARGET), HP-UX)
EXTRA_LIBS += \
$(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
$(NULL)
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
EXTRA_SHARED_LIBS += \
-L$(DIST)/lib/ \
-lplc4 \
-lplds4 \
-lnspr4 \
-lc
#endif
endif

View File

@@ -1,683 +0,0 @@
/*
* des.c
*
* core source file for DES-150 library
* Make key schedule from DES key.
* Encrypt/Decrypt one 8-byte block.
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the DES-150 library.
*
* The Initial Developer of the Original Code is Nelson B. Bolyard,
* nelsonb@iname.com. Portions created by Nelson B. Bolyard are
* Copyright (C) 1990, 2000 Nelson B. Bolyard, All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the GPL.
*/
#include "des.h"
#include <stddef.h> /* for ptrdiff_t */
/* #define USE_INDEXING 1 */
/*
* The tables below are the 8 sbox functions, with the 6-bit input permutation
* and the 32-bit output permutation pre-computed.
* They are shifted circularly to the left 3 bits, which removes 2 shifts
* and an or from each round by reducing the number of sboxes whose
* indices cross word broundaries from 2 to 1.
*/
static const HALF SP[8][64] = {
/* Box S1 */ {
0x04041000, 0x00000000, 0x00040000, 0x04041010,
0x04040010, 0x00041010, 0x00000010, 0x00040000,
0x00001000, 0x04041000, 0x04041010, 0x00001000,
0x04001010, 0x04040010, 0x04000000, 0x00000010,
0x00001010, 0x04001000, 0x04001000, 0x00041000,
0x00041000, 0x04040000, 0x04040000, 0x04001010,
0x00040010, 0x04000010, 0x04000010, 0x00040010,
0x00000000, 0x00001010, 0x00041010, 0x04000000,
0x00040000, 0x04041010, 0x00000010, 0x04040000,
0x04041000, 0x04000000, 0x04000000, 0x00001000,
0x04040010, 0x00040000, 0x00041000, 0x04000010,
0x00001000, 0x00000010, 0x04001010, 0x00041010,
0x04041010, 0x00040010, 0x04040000, 0x04001010,
0x04000010, 0x00001010, 0x00041010, 0x04041000,
0x00001010, 0x04001000, 0x04001000, 0x00000000,
0x00040010, 0x00041000, 0x00000000, 0x04040010
},
/* Box S2 */ {
0x00420082, 0x00020002, 0x00020000, 0x00420080,
0x00400000, 0x00000080, 0x00400082, 0x00020082,
0x00000082, 0x00420082, 0x00420002, 0x00000002,
0x00020002, 0x00400000, 0x00000080, 0x00400082,
0x00420000, 0x00400080, 0x00020082, 0x00000000,
0x00000002, 0x00020000, 0x00420080, 0x00400002,
0x00400080, 0x00000082, 0x00000000, 0x00420000,
0x00020080, 0x00420002, 0x00400002, 0x00020080,
0x00000000, 0x00420080, 0x00400082, 0x00400000,
0x00020082, 0x00400002, 0x00420002, 0x00020000,
0x00400002, 0x00020002, 0x00000080, 0x00420082,
0x00420080, 0x00000080, 0x00020000, 0x00000002,
0x00020080, 0x00420002, 0x00400000, 0x00000082,
0x00400080, 0x00020082, 0x00000082, 0x00400080,
0x00420000, 0x00000000, 0x00020002, 0x00020080,
0x00000002, 0x00400082, 0x00420082, 0x00420000
},
/* Box S3 */ {
0x00000820, 0x20080800, 0x00000000, 0x20080020,
0x20000800, 0x00000000, 0x00080820, 0x20000800,
0x00080020, 0x20000020, 0x20000020, 0x00080000,
0x20080820, 0x00080020, 0x20080000, 0x00000820,
0x20000000, 0x00000020, 0x20080800, 0x00000800,
0x00080800, 0x20080000, 0x20080020, 0x00080820,
0x20000820, 0x00080800, 0x00080000, 0x20000820,
0x00000020, 0x20080820, 0x00000800, 0x20000000,
0x20080800, 0x20000000, 0x00080020, 0x00000820,
0x00080000, 0x20080800, 0x20000800, 0x00000000,
0x00000800, 0x00080020, 0x20080820, 0x20000800,
0x20000020, 0x00000800, 0x00000000, 0x20080020,
0x20000820, 0x00080000, 0x20000000, 0x20080820,
0x00000020, 0x00080820, 0x00080800, 0x20000020,
0x20080000, 0x20000820, 0x00000820, 0x20080000,
0x00080820, 0x00000020, 0x20080020, 0x00080800
},
/* Box S4 */ {
0x02008004, 0x00008204, 0x00008204, 0x00000200,
0x02008200, 0x02000204, 0x02000004, 0x00008004,
0x00000000, 0x02008000, 0x02008000, 0x02008204,
0x00000204, 0x00000000, 0x02000200, 0x02000004,
0x00000004, 0x00008000, 0x02000000, 0x02008004,
0x00000200, 0x02000000, 0x00008004, 0x00008200,
0x02000204, 0x00000004, 0x00008200, 0x02000200,
0x00008000, 0x02008200, 0x02008204, 0x00000204,
0x02000200, 0x02000004, 0x02008000, 0x02008204,
0x00000204, 0x00000000, 0x00000000, 0x02008000,
0x00008200, 0x02000200, 0x02000204, 0x00000004,
0x02008004, 0x00008204, 0x00008204, 0x00000200,
0x02008204, 0x00000204, 0x00000004, 0x00008000,
0x02000004, 0x00008004, 0x02008200, 0x02000204,
0x00008004, 0x00008200, 0x02000000, 0x02008004,
0x00000200, 0x02000000, 0x00008000, 0x02008200
},
/* Box S5 */ {
0x00000400, 0x08200400, 0x08200000, 0x08000401,
0x00200000, 0x00000400, 0x00000001, 0x08200000,
0x00200401, 0x00200000, 0x08000400, 0x00200401,
0x08000401, 0x08200001, 0x00200400, 0x00000001,
0x08000000, 0x00200001, 0x00200001, 0x00000000,
0x00000401, 0x08200401, 0x08200401, 0x08000400,
0x08200001, 0x00000401, 0x00000000, 0x08000001,
0x08200400, 0x08000000, 0x08000001, 0x00200400,
0x00200000, 0x08000401, 0x00000400, 0x08000000,
0x00000001, 0x08200000, 0x08000401, 0x00200401,
0x08000400, 0x00000001, 0x08200001, 0x08200400,
0x00200401, 0x00000400, 0x08000000, 0x08200001,
0x08200401, 0x00200400, 0x08000001, 0x08200401,
0x08200000, 0x00000000, 0x00200001, 0x08000001,
0x00200400, 0x08000400, 0x00000401, 0x00200000,
0x00000000, 0x00200001, 0x08200400, 0x00000401
},
/* Box S6 */ {
0x80000040, 0x81000000, 0x00010000, 0x81010040,
0x81000000, 0x00000040, 0x81010040, 0x01000000,
0x80010000, 0x01010040, 0x01000000, 0x80000040,
0x01000040, 0x80010000, 0x80000000, 0x00010040,
0x00000000, 0x01000040, 0x80010040, 0x00010000,
0x01010000, 0x80010040, 0x00000040, 0x81000040,
0x81000040, 0x00000000, 0x01010040, 0x81010000,
0x00010040, 0x01010000, 0x81010000, 0x80000000,
0x80010000, 0x00000040, 0x81000040, 0x01010000,
0x81010040, 0x01000000, 0x00010040, 0x80000040,
0x01000000, 0x80010000, 0x80000000, 0x00010040,
0x80000040, 0x81010040, 0x01010000, 0x81000000,
0x01010040, 0x81010000, 0x00000000, 0x81000040,
0x00000040, 0x00010000, 0x81000000, 0x01010040,
0x00010000, 0x01000040, 0x80010040, 0x00000000,
0x81010000, 0x80000000, 0x01000040, 0x80010040
},
/* Box S7 */ {
0x00800000, 0x10800008, 0x10002008, 0x00000000,
0x00002000, 0x10002008, 0x00802008, 0x10802000,
0x10802008, 0x00800000, 0x00000000, 0x10000008,
0x00000008, 0x10000000, 0x10800008, 0x00002008,
0x10002000, 0x00802008, 0x00800008, 0x10002000,
0x10000008, 0x10800000, 0x10802000, 0x00800008,
0x10800000, 0x00002000, 0x00002008, 0x10802008,
0x00802000, 0x00000008, 0x10000000, 0x00802000,
0x10000000, 0x00802000, 0x00800000, 0x10002008,
0x10002008, 0x10800008, 0x10800008, 0x00000008,
0x00800008, 0x10000000, 0x10002000, 0x00800000,
0x10802000, 0x00002008, 0x00802008, 0x10802000,
0x00002008, 0x10000008, 0x10802008, 0x10800000,
0x00802000, 0x00000000, 0x00000008, 0x10802008,
0x00000000, 0x00802008, 0x10800000, 0x00002000,
0x10000008, 0x10002000, 0x00002000, 0x00800008
},
/* Box S8 */ {
0x40004100, 0x00004000, 0x00100000, 0x40104100,
0x40000000, 0x40004100, 0x00000100, 0x40000000,
0x00100100, 0x40100000, 0x40104100, 0x00104000,
0x40104000, 0x00104100, 0x00004000, 0x00000100,
0x40100000, 0x40000100, 0x40004000, 0x00004100,
0x00104000, 0x00100100, 0x40100100, 0x40104000,
0x00004100, 0x00000000, 0x00000000, 0x40100100,
0x40000100, 0x40004000, 0x00104100, 0x00100000,
0x00104100, 0x00100000, 0x40104000, 0x00004000,
0x00000100, 0x40100100, 0x00004000, 0x00104100,
0x40004000, 0x00000100, 0x40000100, 0x40100000,
0x40100100, 0x40000000, 0x00100000, 0x40004100,
0x00000000, 0x40104100, 0x00100100, 0x40000100,
0x40100000, 0x40004000, 0x40004100, 0x00000000,
0x40104100, 0x00104000, 0x00104000, 0x00004100,
0x00004100, 0x00100100, 0x40000000, 0x40104000
}
};
static const HALF PC2[8][64] = {
/* table 0 */ {
0x00000000, 0x00001000, 0x04000000, 0x04001000,
0x00100000, 0x00101000, 0x04100000, 0x04101000,
0x00008000, 0x00009000, 0x04008000, 0x04009000,
0x00108000, 0x00109000, 0x04108000, 0x04109000,
0x00000004, 0x00001004, 0x04000004, 0x04001004,
0x00100004, 0x00101004, 0x04100004, 0x04101004,
0x00008004, 0x00009004, 0x04008004, 0x04009004,
0x00108004, 0x00109004, 0x04108004, 0x04109004,
0x08000000, 0x08001000, 0x0c000000, 0x0c001000,
0x08100000, 0x08101000, 0x0c100000, 0x0c101000,
0x08008000, 0x08009000, 0x0c008000, 0x0c009000,
0x08108000, 0x08109000, 0x0c108000, 0x0c109000,
0x08000004, 0x08001004, 0x0c000004, 0x0c001004,
0x08100004, 0x08101004, 0x0c100004, 0x0c101004,
0x08008004, 0x08009004, 0x0c008004, 0x0c009004,
0x08108004, 0x08109004, 0x0c108004, 0x0c109004
},
/* table 1 */ {
0x00000000, 0x00002000, 0x80000000, 0x80002000,
0x00000008, 0x00002008, 0x80000008, 0x80002008,
0x00200000, 0x00202000, 0x80200000, 0x80202000,
0x00200008, 0x00202008, 0x80200008, 0x80202008,
0x20000000, 0x20002000, 0xa0000000, 0xa0002000,
0x20000008, 0x20002008, 0xa0000008, 0xa0002008,
0x20200000, 0x20202000, 0xa0200000, 0xa0202000,
0x20200008, 0x20202008, 0xa0200008, 0xa0202008,
0x00000400, 0x00002400, 0x80000400, 0x80002400,
0x00000408, 0x00002408, 0x80000408, 0x80002408,
0x00200400, 0x00202400, 0x80200400, 0x80202400,
0x00200408, 0x00202408, 0x80200408, 0x80202408,
0x20000400, 0x20002400, 0xa0000400, 0xa0002400,
0x20000408, 0x20002408, 0xa0000408, 0xa0002408,
0x20200400, 0x20202400, 0xa0200400, 0xa0202400,
0x20200408, 0x20202408, 0xa0200408, 0xa0202408
},
/* table 2 */ {
0x00000000, 0x00004000, 0x00000020, 0x00004020,
0x00080000, 0x00084000, 0x00080020, 0x00084020,
0x00000800, 0x00004800, 0x00000820, 0x00004820,
0x00080800, 0x00084800, 0x00080820, 0x00084820,
0x00000010, 0x00004010, 0x00000030, 0x00004030,
0x00080010, 0x00084010, 0x00080030, 0x00084030,
0x00000810, 0x00004810, 0x00000830, 0x00004830,
0x00080810, 0x00084810, 0x00080830, 0x00084830,
0x00400000, 0x00404000, 0x00400020, 0x00404020,
0x00480000, 0x00484000, 0x00480020, 0x00484020,
0x00400800, 0x00404800, 0x00400820, 0x00404820,
0x00480800, 0x00484800, 0x00480820, 0x00484820,
0x00400010, 0x00404010, 0x00400030, 0x00404030,
0x00480010, 0x00484010, 0x00480030, 0x00484030,
0x00400810, 0x00404810, 0x00400830, 0x00404830,
0x00480810, 0x00484810, 0x00480830, 0x00484830
},
/* table 3 */ {
0x00000000, 0x40000000, 0x00000080, 0x40000080,
0x00040000, 0x40040000, 0x00040080, 0x40040080,
0x00000040, 0x40000040, 0x000000c0, 0x400000c0,
0x00040040, 0x40040040, 0x000400c0, 0x400400c0,
0x10000000, 0x50000000, 0x10000080, 0x50000080,
0x10040000, 0x50040000, 0x10040080, 0x50040080,
0x10000040, 0x50000040, 0x100000c0, 0x500000c0,
0x10040040, 0x50040040, 0x100400c0, 0x500400c0,
0x00800000, 0x40800000, 0x00800080, 0x40800080,
0x00840000, 0x40840000, 0x00840080, 0x40840080,
0x00800040, 0x40800040, 0x008000c0, 0x408000c0,
0x00840040, 0x40840040, 0x008400c0, 0x408400c0,
0x10800000, 0x50800000, 0x10800080, 0x50800080,
0x10840000, 0x50840000, 0x10840080, 0x50840080,
0x10800040, 0x50800040, 0x108000c0, 0x508000c0,
0x10840040, 0x50840040, 0x108400c0, 0x508400c0
},
/* table 4 */ {
0x00000000, 0x00000008, 0x08000000, 0x08000008,
0x00040000, 0x00040008, 0x08040000, 0x08040008,
0x00002000, 0x00002008, 0x08002000, 0x08002008,
0x00042000, 0x00042008, 0x08042000, 0x08042008,
0x80000000, 0x80000008, 0x88000000, 0x88000008,
0x80040000, 0x80040008, 0x88040000, 0x88040008,
0x80002000, 0x80002008, 0x88002000, 0x88002008,
0x80042000, 0x80042008, 0x88042000, 0x88042008,
0x00080000, 0x00080008, 0x08080000, 0x08080008,
0x000c0000, 0x000c0008, 0x080c0000, 0x080c0008,
0x00082000, 0x00082008, 0x08082000, 0x08082008,
0x000c2000, 0x000c2008, 0x080c2000, 0x080c2008,
0x80080000, 0x80080008, 0x88080000, 0x88080008,
0x800c0000, 0x800c0008, 0x880c0000, 0x880c0008,
0x80082000, 0x80082008, 0x88082000, 0x88082008,
0x800c2000, 0x800c2008, 0x880c2000, 0x880c2008
},
/* table 5 */ {
0x00000000, 0x00400000, 0x00008000, 0x00408000,
0x40000000, 0x40400000, 0x40008000, 0x40408000,
0x00000020, 0x00400020, 0x00008020, 0x00408020,
0x40000020, 0x40400020, 0x40008020, 0x40408020,
0x00001000, 0x00401000, 0x00009000, 0x00409000,
0x40001000, 0x40401000, 0x40009000, 0x40409000,
0x00001020, 0x00401020, 0x00009020, 0x00409020,
0x40001020, 0x40401020, 0x40009020, 0x40409020,
0x00100000, 0x00500000, 0x00108000, 0x00508000,
0x40100000, 0x40500000, 0x40108000, 0x40508000,
0x00100020, 0x00500020, 0x00108020, 0x00508020,
0x40100020, 0x40500020, 0x40108020, 0x40508020,
0x00101000, 0x00501000, 0x00109000, 0x00509000,
0x40101000, 0x40501000, 0x40109000, 0x40509000,
0x00101020, 0x00501020, 0x00109020, 0x00509020,
0x40101020, 0x40501020, 0x40109020, 0x40509020
},
/* table 6 */ {
0x00000000, 0x00000040, 0x04000000, 0x04000040,
0x00000800, 0x00000840, 0x04000800, 0x04000840,
0x00800000, 0x00800040, 0x04800000, 0x04800040,
0x00800800, 0x00800840, 0x04800800, 0x04800840,
0x10000000, 0x10000040, 0x14000000, 0x14000040,
0x10000800, 0x10000840, 0x14000800, 0x14000840,
0x10800000, 0x10800040, 0x14800000, 0x14800040,
0x10800800, 0x10800840, 0x14800800, 0x14800840,
0x00000080, 0x000000c0, 0x04000080, 0x040000c0,
0x00000880, 0x000008c0, 0x04000880, 0x040008c0,
0x00800080, 0x008000c0, 0x04800080, 0x048000c0,
0x00800880, 0x008008c0, 0x04800880, 0x048008c0,
0x10000080, 0x100000c0, 0x14000080, 0x140000c0,
0x10000880, 0x100008c0, 0x14000880, 0x140008c0,
0x10800080, 0x108000c0, 0x14800080, 0x148000c0,
0x10800880, 0x108008c0, 0x14800880, 0x148008c0
},
/* table 7 */ {
0x00000000, 0x00000010, 0x00000400, 0x00000410,
0x00000004, 0x00000014, 0x00000404, 0x00000414,
0x00004000, 0x00004010, 0x00004400, 0x00004410,
0x00004004, 0x00004014, 0x00004404, 0x00004414,
0x20000000, 0x20000010, 0x20000400, 0x20000410,
0x20000004, 0x20000014, 0x20000404, 0x20000414,
0x20004000, 0x20004010, 0x20004400, 0x20004410,
0x20004004, 0x20004014, 0x20004404, 0x20004414,
0x00200000, 0x00200010, 0x00200400, 0x00200410,
0x00200004, 0x00200014, 0x00200404, 0x00200414,
0x00204000, 0x00204010, 0x00204400, 0x00204410,
0x00204004, 0x00204014, 0x00204404, 0x00204414,
0x20200000, 0x20200010, 0x20200400, 0x20200410,
0x20200004, 0x20200014, 0x20200404, 0x20200414,
0x20204000, 0x20204010, 0x20204400, 0x20204410,
0x20204004, 0x20204014, 0x20204404, 0x20204414
}
};
/*
* The PC-1 Permutation
* If we number the bits of the 8 bytes of key input like this (in octal):
* 00 01 02 03 04 05 06 07
* 10 11 12 13 14 15 16 17
* 20 21 22 23 24 25 26 27
* 30 31 32 33 34 35 36 37
* 40 41 42 43 44 45 46 47
* 50 51 52 53 54 55 56 57
* 60 61 62 63 64 65 66 67
* 70 71 72 73 74 75 76 77
* then after the PC-1 permutation,
* C0 is
* 70 60 50 40 30 20 10 00
* 71 61 51 41 31 21 11 01
* 72 62 52 42 32 22 12 02
* 73 63 53 43
* D0 is
* 76 66 56 46 36 26 16 06
* 75 65 55 45 35 25 15 05
* 74 64 54 44 34 24 14 04
* 33 23 13 03
* and these parity bits have been discarded:
* 77 67 57 47 37 27 17 07
*
* We achieve this by flipping the input matrix about the diagonal from 70-07,
* getting left =
* 77 67 57 47 37 27 17 07 (these are the parity bits)
* 76 66 56 46 36 26 16 06
* 75 65 55 45 35 25 15 05
* 74 64 54 44 34 24 14 04
* right =
* 73 63 53 43 33 23 13 03
* 72 62 52 42 32 22 12 02
* 71 61 51 41 31 21 11 01
* 70 60 50 40 30 20 10 00
* then byte swap right, ala htonl() on a little endian machine.
* right =
* 70 60 50 40 30 20 10 00
* 71 67 57 47 37 27 11 07
* 72 62 52 42 32 22 12 02
* 73 63 53 43 33 23 13 03
* then
* c0 = right >> 4;
* d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
*/
#define FLIP_RIGHT_DIAGONAL(word, temp) \
temp = (word ^ (word >> 18)) & 0x00003333; \
word ^= temp | (temp << 18); \
temp = (word ^ (word >> 9)) & 0x00550055; \
word ^= temp | (temp << 9);
#define BYTESWAP(word, temp) \
word = (word >> 16) | (word << 16); \
temp = 0x00ff00ff; \
word = ((word & temp) << 8) | ((word >> 8) & temp);
#define PC1(left, right, c0, d0, temp) \
right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
left ^= temp << 4; \
FLIP_RIGHT_DIAGONAL(left, temp); \
FLIP_RIGHT_DIAGONAL(right, temp); \
BYTESWAP(right, temp); \
c0 = right >> 4; \
d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
#define LEFT_SHIFT_1( reg ) (((reg << 1) | (reg >> 27)) & 0x0FFFFFFF)
#define LEFT_SHIFT_2( reg ) (((reg << 2) | (reg >> 26)) & 0x0FFFFFFF)
/*
* setup key schedules from key
*/
void
DES_MakeSchedule( HALF * ks, const BYTE * key, DESDirection direction)
{
register HALF left, right;
register HALF c0, d0;
register HALF temp;
int delta;
unsigned int ls;
#if defined(_X86_)
left = HALFPTR(key)[0];
right = HALFPTR(key)[1];
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#else
if (((ptrdiff_t)key & 0x03) == 0) {
left = HALFPTR(key)[0];
right = HALFPTR(key)[1];
#if defined(IS_LITTLE_ENDIAN)
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#endif
} else {
left = ((HALF)key[0] << 24) | ((HALF)key[1] << 16) |
((HALF)key[2] << 8) | key[3];
right = ((HALF)key[4] << 24) | ((HALF)key[5] << 16) |
((HALF)key[6] << 8) | key[7];
}
#endif
PC1(left, right, c0, d0, temp);
if (direction == DES_ENCRYPT) {
delta = 2 * (int)sizeof(HALF);
} else {
ks += 30;
delta = (-2) * (int)sizeof(HALF);
}
for (ls = 0x8103; ls; ls >>= 1) {
if ( ls & 1 ) {
c0 = LEFT_SHIFT_1( c0 );
d0 = LEFT_SHIFT_1( d0 );
} else {
c0 = LEFT_SHIFT_2( c0 );
d0 = LEFT_SHIFT_2( d0 );
}
#ifdef USE_INDEXING
#define PC2LOOKUP(b,c) PC2[b][c]
left = PC2LOOKUP(0, ((c0 >> 22) & 0x3F) );
left |= PC2LOOKUP(1, ((c0 >> 13) & 0x3F) );
left |= PC2LOOKUP(2, ((c0 >> 4) & 0x38) | (c0 & 0x7) );
left |= PC2LOOKUP(3, ((c0>>18)&0xC) | ((c0>>11)&0x3) | (c0&0x30));
right = PC2LOOKUP(4, ((d0 >> 22) & 0x3F) );
right |= PC2LOOKUP(5, ((d0 >> 15) & 0x30) | ((d0 >> 14) & 0xf) );
right |= PC2LOOKUP(6, ((d0 >> 7) & 0x3F) );
right |= PC2LOOKUP(7, ((d0 >> 1) & 0x3C) | (d0 & 0x3));
#else
#define PC2LOOKUP(b,c) *(HALF *)((BYTE *)&PC2[b][0]+(c))
left = PC2LOOKUP(0, ((c0 >> 20) & 0xFC) );
left |= PC2LOOKUP(1, ((c0 >> 11) & 0xFC) );
left |= PC2LOOKUP(2, ((c0 >> 2) & 0xE0) | ((c0 << 2) & 0x1C) );
left |= PC2LOOKUP(3, ((c0>>16)&0x30)|((c0>>9)&0xC)|((c0<<2)&0xC0));
right = PC2LOOKUP(4, ((d0 >> 20) & 0xFC) );
right |= PC2LOOKUP(5, ((d0 >> 13) & 0xC0) | ((d0 >> 12) & 0x3C) );
right |= PC2LOOKUP(6, ((d0 >> 5) & 0xFC) );
right |= PC2LOOKUP(7, ((d0 << 1) & 0xF0) | ((d0 << 2) & 0x0C));
#endif
/* left contains key bits for S1 S3 S2 S4 */
/* right contains key bits for S6 S8 S5 S7 */
temp = (left << 16) /* S2 S4 XX XX */
| (right >> 16); /* XX XX S6 S8 */
ks[0] = temp;
temp = (left & 0xffff0000) /* S1 S3 XX XX */
| (right & 0x0000ffff);/* XX XX S5 S7 */
ks[1] = temp;
ks = (HALF*)((BYTE *)ks + delta);
}
}
/*
* The DES Initial Permutation
* if we number the bits of the 8 bytes of input like this (in octal):
* 00 01 02 03 04 05 06 07
* 10 11 12 13 14 15 16 17
* 20 21 22 23 24 25 26 27
* 30 31 32 33 34 35 36 37
* 40 41 42 43 44 45 46 47
* 50 51 52 53 54 55 56 57
* 60 61 62 63 64 65 66 67
* 70 71 72 73 74 75 76 77
* then after the initial permutation, they will be in this order.
* 71 61 51 41 31 21 11 01
* 73 63 53 43 33 23 13 03
* 75 65 55 45 35 25 15 05
* 77 67 57 47 37 27 17 07
* 70 60 50 40 30 20 10 00
* 72 62 52 42 32 22 12 02
* 74 64 54 44 34 24 14 04
* 76 66 56 46 36 26 16 06
*
* One way to do this is in two steps:
* 1. Flip this matrix about the diagonal from 70-07 as done for PC1.
* 2. Rearrange the bytes (rows in the matrix above) with the following code.
*
* #define swapHiLo(word, temp) \
* temp = (word ^ (word >> 24)) & 0x000000ff; \
* word ^= temp | (temp << 24);
*
* right ^= temp = ((left << 8) ^ right) & 0xff00ff00;
* left ^= temp >> 8;
* swapHiLo(left, temp);
* swapHiLo(right,temp);
*
* However, the two steps can be combined, so that the rows are rearranged
* while the matrix is being flipped, reducing the number of bit exchange
* operations from 8 ot 5.
*
* Initial Permutation */
#define IP(left, right, temp) \
right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
left ^= temp << 4; \
right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
left ^= temp << 16; \
right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \
left ^= temp >> 2; \
right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \
left ^= temp >> 8; \
right ^= temp = ((left >> 1) ^ right) & 0x55555555; \
left ^= temp << 1;
/* The Final (Inverse Initial) permutation is done by reversing the
** steps of the Initital Permutation
*/
#define FP(left, right, temp) \
right ^= temp = ((left >> 1) ^ right) & 0x55555555; \
left ^= temp << 1; \
right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \
left ^= temp >> 8; \
right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \
left ^= temp >> 2; \
right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
left ^= temp << 16; \
right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
left ^= temp << 4;
void
DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
{
register HALF left, right;
register HALF temp;
#if defined(_X86_)
left = HALFPTR(inbuf)[0];
right = HALFPTR(inbuf)[1];
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#else
if (((ptrdiff_t)inbuf & 0x03) == 0) {
left = HALFPTR(inbuf)[0];
right = HALFPTR(inbuf)[1];
#if defined(IS_LITTLE_ENDIAN)
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#endif
} else {
left = ((HALF)inbuf[0] << 24) | ((HALF)inbuf[1] << 16) |
((HALF)inbuf[2] << 8) | inbuf[3];
right = ((HALF)inbuf[4] << 24) | ((HALF)inbuf[5] << 16) |
((HALF)inbuf[6] << 8) | inbuf[7];
}
#endif
IP(left, right, temp);
/* shift the values left circularly 3 bits. */
left = (left << 3) | (left >> 29);
right = (right << 3) | (right >> 29);
#ifdef USE_INDEXING
#define KSLOOKUP(s,b) SP[s][((temp >> (b+2)) & 0x3f)]
#else
#define KSLOOKUP(s,b) *(HALF*)((BYTE*)&SP[s][0]+((temp >> b) & 0xFC))
#endif
#define ROUND(out, in, r) \
temp = in ^ ks[2*r]; \
out ^= KSLOOKUP( 1, 24 ); \
out ^= KSLOOKUP( 3, 16 ); \
out ^= KSLOOKUP( 5, 8 ); \
out ^= KSLOOKUP( 7, 0 ); \
temp = ((in >> 4) | (in << 28)) ^ ks[2*r+1]; \
out ^= KSLOOKUP( 0, 24 ); \
out ^= KSLOOKUP( 2, 16 ); \
out ^= KSLOOKUP( 4, 8 ); \
out ^= KSLOOKUP( 6, 0 );
/* Do the 16 Feistel rounds */
ROUND(left, right, 0)
ROUND(right, left, 1)
ROUND(left, right, 2)
ROUND(right, left, 3)
ROUND(left, right, 4)
ROUND(right, left, 5)
ROUND(left, right, 6)
ROUND(right, left, 7)
ROUND(left, right, 8)
ROUND(right, left, 9)
ROUND(left, right, 10)
ROUND(right, left, 11)
ROUND(left, right, 12)
ROUND(right, left, 13)
ROUND(left, right, 14)
ROUND(right, left, 15)
/* now shift circularly right 3 bits to undo the shifting done
** above. switch left and right here.
*/
temp = (left >> 3) | (left << 29);
left = (right >> 3) | (right << 29);
right = temp;
FP(left, right, temp);
#if defined(_X86_)
BYTESWAP(left, temp);
BYTESWAP(right, temp);
HALFPTR(outbuf)[0] = left;
HALFPTR(outbuf)[1] = right;
#else
if (((ptrdiff_t)inbuf & 0x03) == 0) {
#if defined(IS_LITTLE_ENDIAN)
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#endif
HALFPTR(outbuf)[0] = left;
HALFPTR(outbuf)[1] = right;
} else {
outbuf[0] = (BYTE)(left >> 24);
outbuf[1] = (BYTE)(left >> 16);
outbuf[2] = (BYTE)(left >> 8);
outbuf[3] = (BYTE)(left );
outbuf[4] = (BYTE)(right >> 24);
outbuf[5] = (BYTE)(right >> 16);
outbuf[6] = (BYTE)(right >> 8);
outbuf[7] = (BYTE)(right );
}
#endif
}
/* Ackowledgements:
** Two ideas used in this implementation were shown to me by Dennis Ferguson
** in 1990. He credits them to Richard Outerbridge and Dan Hoey. They were:
** 1. The method of computing the Initial and Final permutations.
** 2. Circularly rotating the SP tables and the initial values of left and
** right to reduce the number of shifts required during the 16 rounds.
*/

View File

@@ -1,69 +0,0 @@
/*
* des.h
*
* header file for DES-150 library
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the DES-150 library.
*
* The Initial Developer of the Original Code is Nelson B. Bolyard,
* nelsonb@iname.com. Portions created by Nelson B. Bolyard are
* Copyright (C) 1990, 2000 Nelson B. Bolyard, All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the GPL.
*/
#ifndef _DES_H_
#define _DES_H_ 1
#include "blapi.h"
typedef unsigned char BYTE;
typedef unsigned int HALF;
#define HALFPTR(x) ((HALF *)(x))
#define SHORTPTR(x) ((unsigned short *)(x))
#define BYTEPTR(x) ((BYTE *)(x))
typedef enum {
DES_ENCRYPT = 0x5555,
DES_DECRYPT = 0xAAAA
} DESDirection;
typedef void DESFunc(struct DESContextStr *cx, BYTE *out, const BYTE *in,
unsigned int len);
struct DESContextStr {
/* key schedule, 16 internal keys, each with 8 6-bit parts */
HALF ks0 [32];
HALF ks1 [32];
HALF ks2 [32];
HALF iv [2];
DESDirection direction;
DESFunc *worker;
};
void DES_MakeSchedule( HALF * ks, const BYTE * key, DESDirection direction);
void DES_Do1Block( HALF * ks, const BYTE * inbuf, BYTE * outbuf);
#endif

View File

@@ -1,275 +0,0 @@
/*
* desblapi.c
*
* core source file for DES-150 library
* Implement DES Modes of Operation and Triple-DES.
* Adapt DES-150 to blapi API.
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the DES-150 library.
*
* The Initial Developer of the Original Code is Nelson B. Bolyard,
* nelsonb@iname.com. Portions created by Nelson B. Bolyard are
* Copyright (C) 1990, 2000 Nelson B. Bolyard, All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the GPL.
*/
#include "des.h"
#include <stddef.h>
#include "secerr.h"
#if defined(_X86_)
/* Intel X86 CPUs do unaligned loads and stores without complaint. */
#define COPY8B(to, from, ptr) \
HALFPTR(to)[0] = HALFPTR(from)[0]; \
HALFPTR(to)[1] = HALFPTR(from)[1];
#elif defined(USE_MEMCPY)
#define COPY8B(to, from, ptr) memcpy(to, from, 8)
#else
#define COPY8B(to, from, ptr) \
if (((ptrdiff_t)(ptr) & 0x3) == 0) { \
HALFPTR(to)[0] = HALFPTR(from)[0]; \
HALFPTR(to)[1] = HALFPTR(from)[1]; \
} else if (((ptrdiff_t)(ptr) & 0x1) == 0) { \
SHORTPTR(to)[0] = SHORTPTR(from)[0]; \
SHORTPTR(to)[1] = SHORTPTR(from)[1]; \
SHORTPTR(to)[2] = SHORTPTR(from)[2]; \
SHORTPTR(to)[3] = SHORTPTR(from)[3]; \
} else { \
BYTEPTR(to)[0] = BYTEPTR(from)[0]; \
BYTEPTR(to)[1] = BYTEPTR(from)[1]; \
BYTEPTR(to)[2] = BYTEPTR(from)[2]; \
BYTEPTR(to)[3] = BYTEPTR(from)[3]; \
BYTEPTR(to)[4] = BYTEPTR(from)[4]; \
BYTEPTR(to)[5] = BYTEPTR(from)[5]; \
BYTEPTR(to)[6] = BYTEPTR(from)[6]; \
BYTEPTR(to)[7] = BYTEPTR(from)[7]; \
}
#endif
#define COPY8BTOHALF(to, from) COPY8B(to, from, from)
#define COPY8BFROMHALF(to, from) COPY8B(to, from, to)
static void
DES_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
while (len) {
DES_Do1Block(cx->ks0, in, out);
len -= 8;
in += 8;
out += 8;
}
}
static void
DES_EDE3_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
while (len) {
DES_Do1Block(cx->ks0, in, out);
len -= 8;
in += 8;
DES_Do1Block(cx->ks1, out, out);
DES_Do1Block(cx->ks2, out, out);
out += 8;
}
}
static void
DES_CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
const BYTE * bufend = in + len;
HALF vec[2];
while (in != bufend) {
COPY8BTOHALF(vec, in);
in += 8;
vec[0] ^= cx->iv[0];
vec[1] ^= cx->iv[1];
DES_Do1Block( cx->ks0, (BYTE *)vec, (BYTE *)cx->iv);
COPY8BFROMHALF(out, cx->iv);
out += 8;
}
}
static void
DES_CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
const BYTE * bufend;
HALF oldciphertext[2];
HALF plaintext [2];
for (bufend = in + len; in != bufend; ) {
oldciphertext[0] = cx->iv[0];
oldciphertext[1] = cx->iv[1];
COPY8BTOHALF(cx->iv, in);
in += 8;
DES_Do1Block(cx->ks0, (BYTE *)cx->iv, (BYTE *)plaintext);
plaintext[0] ^= oldciphertext[0];
plaintext[1] ^= oldciphertext[1];
COPY8BFROMHALF(out, plaintext);
out += 8;
}
}
static void
DES_EDE3CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
const BYTE * bufend = in + len;
HALF vec[2];
while (in != bufend) {
COPY8BTOHALF(vec, in);
in += 8;
vec[0] ^= cx->iv[0];
vec[1] ^= cx->iv[1];
DES_Do1Block( cx->ks0, (BYTE *)vec, (BYTE *)cx->iv);
DES_Do1Block( cx->ks1, (BYTE *)cx->iv, (BYTE *)cx->iv);
DES_Do1Block( cx->ks2, (BYTE *)cx->iv, (BYTE *)cx->iv);
COPY8BFROMHALF(out, cx->iv);
out += 8;
}
}
static void
DES_EDE3CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
const BYTE * bufend;
HALF oldciphertext[2];
HALF plaintext [2];
for (bufend = in + len; in != bufend; ) {
oldciphertext[0] = cx->iv[0];
oldciphertext[1] = cx->iv[1];
COPY8BTOHALF(cx->iv, in);
in += 8;
DES_Do1Block(cx->ks0, (BYTE *)cx->iv, (BYTE *)plaintext);
DES_Do1Block(cx->ks1, (BYTE *)plaintext, (BYTE *)plaintext);
DES_Do1Block(cx->ks2, (BYTE *)plaintext, (BYTE *)plaintext);
plaintext[0] ^= oldciphertext[0];
plaintext[1] ^= oldciphertext[1];
COPY8BFROMHALF(out, plaintext);
out += 8;
}
}
DESContext *
DES_CreateContext(const BYTE * key, const BYTE *iv, int mode, PRBool encrypt)
{
DESContext *cx = PORT_ZNew(DESContext);
DESDirection opposite;
if (!cx)
return 0;
cx->direction = encrypt ? DES_ENCRYPT : DES_DECRYPT;
opposite = encrypt ? DES_DECRYPT : DES_ENCRYPT;
switch (mode) {
case NSS_DES: /* DES ECB */
DES_MakeSchedule( cx->ks0, key, cx->direction);
cx->worker = &DES_ECB;
break;
case NSS_DES_EDE3: /* DES EDE ECB */
cx->worker = &DES_EDE3_ECB;
if (encrypt) {
DES_MakeSchedule(cx->ks0, key, cx->direction);
DES_MakeSchedule(cx->ks1, key + 8, opposite);
DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
} else {
DES_MakeSchedule(cx->ks2, key, cx->direction);
DES_MakeSchedule(cx->ks1, key + 8, opposite);
DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
}
break;
case NSS_DES_CBC: /* DES CBC */
COPY8BTOHALF(cx->iv, iv);
cx->worker = encrypt ? &DES_CBCEn : &DES_CBCDe;
DES_MakeSchedule(cx->ks0, key, cx->direction);
break;
case NSS_DES_EDE3_CBC: /* DES EDE CBC */
COPY8BTOHALF(cx->iv, iv);
if (encrypt) {
cx->worker = &DES_EDE3CBCEn;
DES_MakeSchedule(cx->ks0, key, cx->direction);
DES_MakeSchedule(cx->ks1, key + 8, opposite);
DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
} else {
cx->worker = &DES_EDE3CBCDe;
DES_MakeSchedule(cx->ks2, key, cx->direction);
DES_MakeSchedule(cx->ks1, key + 8, opposite);
DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
}
break;
default:
PORT_Free(cx);
cx = 0;
PORT_SetError(SEC_ERROR_INVALID_ARGS);
break;
}
return cx;
}
void
DES_DestroyContext(DESContext *cx, PRBool freeit)
{
if (cx) {
memset(cx, 0, sizeof *cx);
if (freeit)
PORT_Free(cx);
}
}
SECStatus
DES_Encrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
{
if (inLen < 0 || (inLen % 8) != 0 || maxOutLen < inLen || !cx ||
cx->direction != DES_ENCRYPT) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
cx->worker(cx, out, in, inLen);
if (outLen)
*outLen = inLen;
return SECSuccess;
}
SECStatus
DES_Decrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
{
if (inLen < 0 || (inLen % 8) != 0 || maxOutLen < inLen || !cx ||
cx->direction != DES_DECRYPT) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
cx->worker(cx, out, in, inLen);
if (outLen)
*outLen = inLen;
return SECSuccess;
}

View File

@@ -1,385 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
/*
* Diffie-Hellman parameter generation, key generation, and secret derivation.
* KEA secret generation and verification.
*
* $Id: dh.c,v 1.6 2001-09-20 22:14:06 relyea%netscape.com Exp $
*/
#include "prerr.h"
#include "secerr.h"
#include "blapi.h"
#include "secitem.h"
#include "mpi.h"
#include "mpprime.h"
#include "secmpi.h"
#define DH_SECRET_KEY_LEN 20
#define KEA_DERIVED_SECRET_LEN 128
SECStatus
DH_GenParam(int primeLen, DHParams **params)
{
PRArenaPool *arena;
DHParams *dhparams;
unsigned char *pb = NULL;
unsigned char *ab = NULL;
unsigned long counter = 0;
mp_int p, q, a, h, psub1, test;
mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
if (!params || primeLen < 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
if (!arena) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
}
dhparams = (DHParams *)PORT_ArenaZAlloc(arena, sizeof(DHParams));
if (!dhparams) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
dhparams->arena = arena;
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
MP_DIGITS(&a) = 0;
MP_DIGITS(&h) = 0;
MP_DIGITS(&psub1) = 0;
MP_DIGITS(&test) = 0;
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&q) );
CHECK_MPI_OK( mp_init(&a) );
CHECK_MPI_OK( mp_init(&h) );
CHECK_MPI_OK( mp_init(&psub1) );
CHECK_MPI_OK( mp_init(&test) );
/* generate prime with MPI, uses Miller-Rabin to generate strong prime. */
pb = PORT_Alloc(primeLen);
CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(pb, primeLen) );
pb[0] |= 0x80; /* set high-order bit */
pb[primeLen-1] |= 0x01; /* set low-order bit */
CHECK_MPI_OK( mp_read_unsigned_octets(&p, pb, primeLen) );
CHECK_MPI_OK( mpp_make_prime(&p, primeLen * 8, PR_TRUE, &counter) );
/* construct Sophie-Germain prime q = (p-1)/2. */
CHECK_MPI_OK( mp_sub_d(&p, 1, &psub1) );
CHECK_MPI_OK( mp_div_2(&psub1, &q) );
/* construct a generator from the prime. */
ab = PORT_Alloc(primeLen);
/* generate a candidate number a in p's field */
CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(ab, primeLen) );
CHECK_MPI_OK( mp_read_unsigned_octets(&a, ab, primeLen) );
/* force a < p (note that quot(a/p) <= 1) */
if ( mp_cmp(&a, &p) > 0 )
CHECK_MPI_OK( mp_sub(&a, &p, &a) );
do {
/* check that a is in the range [2..p-1] */
if ( mp_cmp_d(&a, 2) < 0 || mp_cmp(&a, &psub1) >= 0) {
/* a is outside of the allowed range. Set a=3 and keep going. */
mp_set(&a, 3);
}
/* if a**q mod p != 1 then a is a generator */
CHECK_MPI_OK( mp_exptmod(&a, &q, &p, &test) );
if ( mp_cmp_d(&test, 1) != 0 )
break;
/* increment the candidate and try again. */
CHECK_MPI_OK( mp_add_d(&a, 1, &a) );
} while (PR_TRUE);
MPINT_TO_SECITEM(&p, &dhparams->prime, arena);
MPINT_TO_SECITEM(&a, &dhparams->base, arena);
*params = dhparams;
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&a);
mp_clear(&h);
mp_clear(&psub1);
mp_clear(&test);
if (pb) PORT_ZFree(pb, primeLen);
if (ab) PORT_ZFree(ab, primeLen);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
if (rv)
PORT_FreeArena(arena, PR_TRUE);
return rv;
}
SECStatus
DH_NewKey(DHParams *params, DHPrivateKey **privKey)
{
PRArenaPool *arena;
DHPrivateKey *key;
mp_int g, xa, p, Ya;
mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
if (!params || !privKey) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
if (!arena) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
}
key = (DHPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DHPrivateKey));
if (!key) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
key->arena = arena;
MP_DIGITS(&g) = 0;
MP_DIGITS(&xa) = 0;
MP_DIGITS(&p) = 0;
MP_DIGITS(&Ya) = 0;
CHECK_MPI_OK( mp_init(&g) );
CHECK_MPI_OK( mp_init(&xa) );
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&Ya) );
/* Set private key's p */
CHECK_SEC_OK( SECITEM_CopyItem(arena, &key->prime, &params->prime) );
SECITEM_TO_MPINT(key->prime, &p);
/* Set private key's g */
CHECK_SEC_OK( SECITEM_CopyItem(arena, &key->base, &params->base) );
SECITEM_TO_MPINT(key->base, &g);
/* Generate private key xa */
SECITEM_AllocItem(arena, &key->privateValue, DH_SECRET_KEY_LEN);
RNG_GenerateGlobalRandomBytes(key->privateValue.data,
key->privateValue.len);
SECITEM_TO_MPINT( key->privateValue, &xa );
/* xa < p */
CHECK_MPI_OK( mp_mod(&xa, &p, &xa) );
/* Compute public key Ya = g ** xa mod p */
CHECK_MPI_OK( mp_exptmod(&g, &xa, &p, &Ya) );
MPINT_TO_SECITEM(&Ya, &key->publicValue, key->arena);
*privKey = key;
cleanup:
mp_clear(&g);
mp_clear(&xa);
mp_clear(&p);
mp_clear(&Ya);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
if (rv)
PORT_FreeArena(arena, PR_TRUE);
return rv;
}
SECStatus
DH_Derive(SECItem *publicValue,
SECItem *prime,
SECItem *privateValue,
SECItem *derivedSecret,
unsigned int maxOutBytes)
{
mp_int p, Xa, Yb, ZZ;
mp_err err = MP_OKAY;
unsigned int len = 0, nb;
unsigned char *secret = NULL;
if (!publicValue || !prime || !privateValue || !derivedSecret) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
memset(derivedSecret, 0, sizeof *derivedSecret);
MP_DIGITS(&p) = 0;
MP_DIGITS(&Xa) = 0;
MP_DIGITS(&Yb) = 0;
MP_DIGITS(&ZZ) = 0;
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&Xa) );
CHECK_MPI_OK( mp_init(&Yb) );
CHECK_MPI_OK( mp_init(&ZZ) );
SECITEM_TO_MPINT(*publicValue, &Yb);
SECITEM_TO_MPINT(*privateValue, &Xa);
SECITEM_TO_MPINT(*prime, &p);
/* ZZ = (Yb)**Xa mod p */
CHECK_MPI_OK( mp_exptmod(&Yb, &Xa, &p, &ZZ) );
/* number of bytes in the derived secret */
len = mp_unsigned_octet_size(&ZZ);
/* allocate a buffer which can hold the entire derived secret. */
secret = PORT_Alloc(len);
/* grab the derived secret */
err = mp_to_unsigned_octets(&ZZ, secret, len);
if (err >= 0) err = MP_OKAY;
/* Take minimum of bytes requested and bytes in derived secret,
** if maxOutBytes is 0 take all of the bytes from the derived secret.
*/
if (maxOutBytes > 0)
nb = PR_MIN(len, maxOutBytes);
else
nb = len;
SECITEM_AllocItem(NULL, derivedSecret, nb);
memcpy(derivedSecret->data, secret, nb);
cleanup:
mp_clear(&p);
mp_clear(&Xa);
mp_clear(&Yb);
mp_clear(&ZZ);
if (secret) {
/* free the buffer allocated for the full secret. */
PORT_ZFree(secret, len);
}
if (err) {
MP_TO_SEC_ERROR(err);
if (derivedSecret->data)
PORT_ZFree(derivedSecret->data, derivedSecret->len);
return SECFailure;
}
return SECSuccess;
}
SECStatus
KEA_Derive(SECItem *prime,
SECItem *public1,
SECItem *public2,
SECItem *private1,
SECItem *private2,
SECItem *derivedSecret)
{
mp_int p, Y, R, r, x, t, u, w;
mp_err err;
unsigned char *secret = NULL;
unsigned int len = 0, offset;
if (!prime || !public1 || !public2 || !private1 || !private2 ||
!derivedSecret) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
memset(derivedSecret, 0, sizeof *derivedSecret);
MP_DIGITS(&p) = 0;
MP_DIGITS(&Y) = 0;
MP_DIGITS(&R) = 0;
MP_DIGITS(&r) = 0;
MP_DIGITS(&x) = 0;
MP_DIGITS(&t) = 0;
MP_DIGITS(&u) = 0;
MP_DIGITS(&w) = 0;
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&Y) );
CHECK_MPI_OK( mp_init(&R) );
CHECK_MPI_OK( mp_init(&r) );
CHECK_MPI_OK( mp_init(&x) );
CHECK_MPI_OK( mp_init(&t) );
CHECK_MPI_OK( mp_init(&u) );
CHECK_MPI_OK( mp_init(&w) );
SECITEM_TO_MPINT(*prime, &p);
SECITEM_TO_MPINT(*public1, &Y);
SECITEM_TO_MPINT(*public2, &R);
SECITEM_TO_MPINT(*private1, &r);
SECITEM_TO_MPINT(*private2, &x);
/* t = DH(Y, r, p) = Y ** r mod p */
CHECK_MPI_OK( mp_exptmod(&Y, &r, &p, &t) );
/* u = DH(R, x, p) = R ** x mod p */
CHECK_MPI_OK( mp_exptmod(&R, &x, &p, &u) );
/* w = (t + u) mod p */
CHECK_MPI_OK( mp_addmod(&t, &u, &p, &w) );
/* allocate a buffer for the full derived secret */
len = mp_unsigned_octet_size(&w);
secret = PORT_Alloc(len);
/* grab the secret */
err = mp_to_unsigned_octets(&w, secret, len);
if (err > 0) err = MP_OKAY;
/* allocate output buffer */
SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN);
memset(derivedSecret->data, 0, derivedSecret->len);
/* copy in the 128 lsb of the secret */
if (len >= KEA_DERIVED_SECRET_LEN) {
memcpy(derivedSecret->data, secret + (len - KEA_DERIVED_SECRET_LEN),
KEA_DERIVED_SECRET_LEN);
} else {
offset = KEA_DERIVED_SECRET_LEN - len;
memcpy(derivedSecret->data + offset, secret, len);
}
cleanup:
mp_clear(&p);
mp_clear(&Y);
mp_clear(&R);
mp_clear(&r);
mp_clear(&x);
mp_clear(&t);
mp_clear(&u);
mp_clear(&w);
if (secret)
PORT_ZFree(secret, len);
if (err) {
MP_TO_SEC_ERROR(err);
return SECFailure;
}
return SECSuccess;
}
PRBool
KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
{
mp_int p, q, y, r;
mp_err err;
int cmp = 1; /* default is false */
if (!Y || !prime || !subPrime) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
MP_DIGITS(&y) = 0;
MP_DIGITS(&r) = 0;
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&q) );
CHECK_MPI_OK( mp_init(&y) );
CHECK_MPI_OK( mp_init(&r) );
SECITEM_TO_MPINT(*prime, &p);
SECITEM_TO_MPINT(*subPrime, &q);
SECITEM_TO_MPINT(*Y, &y);
/* compute r = y**q mod p */
CHECK_MPI_OK( mp_exptmod(&y, &q, &p, &r) );
/* compare to 1 */
cmp = mp_cmp_d(&r, 1);
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&y);
mp_clear(&r);
if (err) {
MP_TO_SEC_ERROR(err);
return PR_FALSE;
}
return (cmp == 0) ? PR_TRUE : PR_FALSE;
}

View File

@@ -1,82 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "prerr.h"
#include "secerr.h"
#include "blapi.h"
SECStatus
DH_GenParam(int primeLen, DHParams ** params)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
}
SECStatus
DH_NewKey(DHParams * params,
DHPrivateKey ** privKey)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
}
SECStatus
DH_Derive(SECItem * publicValue,
SECItem * prime,
SECItem * privateValue,
SECItem * derivedSecret,
unsigned int maxOutBytes)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
}
SECStatus
KEA_Derive(SECItem *prime,
SECItem *public1,
SECItem *public2,
SECItem *private1,
SECItem *private2,
SECItem *derivedSecret)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
}
PRBool
KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return PR_FALSE;
}

View File

@@ -1,420 +0,0 @@
/*
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: dsa.c,v 1.11 2003-02-25 23:45:23 nelsonb%netscape.com Exp $
*/
#include "secerr.h"
#include "prtypes.h"
#include "prinit.h"
#include "blapi.h"
#include "nssilock.h"
#include "secitem.h"
#include "blapi.h"
#include "mpi.h"
/* XXX to be replaced by define in blapit.h */
#define NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE 2048
#define CHECKOK(func) if (MP_OKAY > (err = func)) goto cleanup
#define SECITEM_TO_MPINT(it, mp) \
CHECKOK(mp_read_unsigned_octets((mp), (it).data, (it).len))
/* DSA-specific random number functions defined in prng_fips1861.c. */
extern SECStatus
DSA_RandomUpdate(void *data, size_t bytes, unsigned char *q);
extern SECStatus
DSA_GenerateGlobalRandomBytes(void *dest, size_t len, unsigned char *q);
static void translate_mpi_error(mp_err err)
{
switch (err) {
case MP_MEM: PORT_SetError(SEC_ERROR_NO_MEMORY); break;
case MP_RANGE: PORT_SetError(SEC_ERROR_BAD_DATA); break;
case MP_BADARG: PORT_SetError(SEC_ERROR_INVALID_ARGS); break;
default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); break;
}
}
SECStatus
dsa_NewKey(const PQGParams *params, DSAPrivateKey **privKey,
const unsigned char *xb)
{
unsigned int y_len;
mp_int p, g;
mp_int x, y;
mp_err err;
PRArenaPool *arena;
DSAPrivateKey *key;
/* Check args. */
if (!params || !privKey) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Initialize an arena for the DSA key. */
arena = PORT_NewArena(NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE);
if (!arena) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
}
key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
if (!key) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
key->params.arena = arena;
/* Initialize MPI integers. */
MP_DIGITS(&p) = 0;
MP_DIGITS(&g) = 0;
MP_DIGITS(&x) = 0;
MP_DIGITS(&y) = 0;
CHECKOK( mp_init(&p) );
CHECKOK( mp_init(&g) );
CHECKOK( mp_init(&x) );
CHECKOK( mp_init(&y) );
/* Copy over the PQG params */
CHECKOK( SECITEM_CopyItem(arena, &key->params.prime, &params->prime) );
CHECKOK( SECITEM_CopyItem(arena, &key->params.subPrime, &params->subPrime));
CHECKOK( SECITEM_CopyItem(arena, &key->params.base, &params->base) );
/* Convert stored p, g, and received x into MPI integers. */
SECITEM_TO_MPINT(params->prime, &p);
SECITEM_TO_MPINT(params->base, &g);
CHECKOK( mp_read_unsigned_octets(&x, xb, DSA_SUBPRIME_LEN) );
/* Store x in private key */
SECITEM_AllocItem(arena, &key->privateValue, DSA_SUBPRIME_LEN);
memcpy(key->privateValue.data, xb, DSA_SUBPRIME_LEN);
/* Compute public key y = g**x mod p */
CHECKOK( mp_exptmod(&g, &x, &p, &y) );
/* Store y in public key */
y_len = mp_unsigned_octet_size(&y);
SECITEM_AllocItem(arena, &key->publicValue, y_len);
err = mp_to_unsigned_octets(&y, key->publicValue.data, y_len);
/* mp_to_unsigned_octets returns bytes written (y_len) if okay */
if (err < 0) goto cleanup; else err = MP_OKAY;
*privKey = key;
key = NULL;
cleanup:
mp_clear(&p);
mp_clear(&g);
mp_clear(&x);
mp_clear(&y);
if (key)
PORT_FreeArena(key->params.arena, PR_TRUE);
if (err) {
translate_mpi_error(err);
return SECFailure;
}
return SECSuccess;
}
/*
** Generate and return a new DSA public and private key pair,
** both of which are encoded into a single DSAPrivateKey struct.
** "params" is a pointer to the PQG parameters for the domain
** Uses a random seed.
*/
SECStatus
DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
{
SECStatus rv;
unsigned char seed[DSA_SUBPRIME_LEN];
/* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
if (DSA_GenerateGlobalRandomBytes(seed, DSA_SUBPRIME_LEN,
params->subPrime.data))
return SECFailure;
/* Generate a new DSA key using random seed. */
rv = dsa_NewKey(params, privKey, seed);
return rv;
}
/* For FIPS compliance testing. Seed must be exactly 20 bytes long */
SECStatus
DSA_NewKeyFromSeed(const PQGParams *params,
const unsigned char *seed,
DSAPrivateKey **privKey)
{
SECStatus rv;
rv = dsa_NewKey(params, privKey, seed);
return rv;
}
static SECStatus
dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
const unsigned char *kb)
{
mp_int p, q, g; /* PQG parameters */
mp_int x, k; /* private key & pseudo-random integer */
mp_int r, s; /* tuple (r, s) is signature) */
mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
/* FIPS-compliance dictates that digest is a SHA1 hash. */
/* Check args. */
if (!key || !signature || !digest ||
(signature->len != DSA_SIGNATURE_LEN) ||
(digest->len != SHA1_LENGTH)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Initialize MPI integers. */
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
MP_DIGITS(&g) = 0;
MP_DIGITS(&x) = 0;
MP_DIGITS(&k) = 0;
MP_DIGITS(&r) = 0;
MP_DIGITS(&s) = 0;
CHECKOK( mp_init(&p) );
CHECKOK( mp_init(&q) );
CHECKOK( mp_init(&g) );
CHECKOK( mp_init(&x) );
CHECKOK( mp_init(&k) );
CHECKOK( mp_init(&r) );
CHECKOK( mp_init(&s) );
/*
** Convert stored PQG and private key into MPI integers.
*/
SECITEM_TO_MPINT(key->params.prime, &p);
SECITEM_TO_MPINT(key->params.subPrime, &q);
SECITEM_TO_MPINT(key->params.base, &g);
SECITEM_TO_MPINT(key->privateValue, &x);
CHECKOK( mp_read_unsigned_octets(&k, kb, DSA_SUBPRIME_LEN) );
/*
** FIPS 186-1, Section 5, Step 1
**
** r = (g**k mod p) mod q
*/
CHECKOK( mp_exptmod(&g, &k, &p, &r) ); /* r = g**k mod p */
CHECKOK( mp_mod(&r, &q, &r) ); /* r = r mod q */
/*
** FIPS 186-1, Section 5, Step 2
**
** s = (k**-1 * (SHA1(M) + x*r)) mod q
*/
SECITEM_TO_MPINT(*digest, &s); /* s = SHA1(M) */
CHECKOK( mp_invmod(&k, &q, &k) ); /* k = k**-1 mod q */
CHECKOK( mp_mulmod(&x, &r, &q, &x) ); /* x = x * r mod q */
CHECKOK( mp_addmod(&s, &x, &q, &s) ); /* s = s + x mod q */
CHECKOK( mp_mulmod(&s, &k, &q, &s) ); /* s = s * k mod q */
/*
** verify r != 0 and s != 0
** mentioned as optional in FIPS 186-1.
*/
if (mp_cmp_z(&r) == 0 || mp_cmp_z(&s) == 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
rv = SECFailure;
goto cleanup;
}
/*
** Step 4
**
** Signature is tuple (r, s)
*/
err = mp_to_fixlen_octets(&r, signature->data, DSA_SUBPRIME_LEN);
if (err < 0) goto cleanup;
err = mp_to_fixlen_octets(&s, signature->data + DSA_SUBPRIME_LEN,
DSA_SUBPRIME_LEN);
if (err < 0) goto cleanup;
err = MP_OKAY;
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
mp_clear(&x);
mp_clear(&k);
mp_clear(&r);
mp_clear(&s);
if (err) {
translate_mpi_error(err);
rv = SECFailure;
}
return rv;
}
/* signature is caller-supplied buffer of at least 20 bytes.
** On input, signature->len == size of buffer to hold signature.
** digest->len == size of digest.
** On output, signature->len == size of signature in buffer.
** Uses a random seed.
*/
SECStatus
DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
{
SECStatus rv;
int retries = 10;
unsigned char kSeed[DSA_SUBPRIME_LEN];
PORT_SetError(0);
do {
rv = DSA_GenerateGlobalRandomBytes(kSeed, DSA_SUBPRIME_LEN,
key->params.subPrime.data);
if (rv != SECSuccess)
break;
rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
--retries > 0);
return rv;
}
/* For FIPS compliance testing. Seed must be exactly 20 bytes. */
SECStatus
DSA_SignDigestWithSeed(DSAPrivateKey * key,
SECItem * signature,
const SECItem * digest,
const unsigned char * seed)
{
SECStatus rv;
rv = dsa_SignDigest(key, signature, digest, seed);
return rv;
}
/* signature is caller-supplied buffer of at least 20 bytes.
** On input, signature->len == size of buffer to hold signature.
** digest->len == size of digest.
*/
SECStatus
DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
const SECItem *digest)
{
/* FIPS-compliance dictates that digest is a SHA1 hash. */
mp_int p, q, g; /* PQG parameters */
mp_int r_, s_; /* tuple (r', s') is received signature) */
mp_int u1, u2, v, w; /* intermediate values used in verification */
mp_int y; /* public key */
mp_err err;
SECStatus verified = SECFailure;
/* Check args. */
if (!key || !signature || !digest ||
(signature->len != DSA_SIGNATURE_LEN) ||
(digest->len != SHA1_LENGTH)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Initialize MPI integers. */
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
MP_DIGITS(&g) = 0;
MP_DIGITS(&y) = 0;
MP_DIGITS(&r_) = 0;
MP_DIGITS(&s_) = 0;
MP_DIGITS(&u1) = 0;
MP_DIGITS(&u2) = 0;
MP_DIGITS(&v) = 0;
MP_DIGITS(&w) = 0;
CHECKOK( mp_init(&p) );
CHECKOK( mp_init(&q) );
CHECKOK( mp_init(&g) );
CHECKOK( mp_init(&y) );
CHECKOK( mp_init(&r_) );
CHECKOK( mp_init(&s_) );
CHECKOK( mp_init(&u1) );
CHECKOK( mp_init(&u2) );
CHECKOK( mp_init(&v) );
CHECKOK( mp_init(&w) );
/*
** Convert stored PQG and public key into MPI integers.
*/
SECITEM_TO_MPINT(key->params.prime, &p);
SECITEM_TO_MPINT(key->params.subPrime, &q);
SECITEM_TO_MPINT(key->params.base, &g);
SECITEM_TO_MPINT(key->publicValue, &y);
/*
** Convert received signature (r', s') into MPI integers.
*/
CHECKOK( mp_read_unsigned_octets(&r_, signature->data, DSA_SUBPRIME_LEN) );
CHECKOK( mp_read_unsigned_octets(&s_, signature->data + DSA_SUBPRIME_LEN,
DSA_SUBPRIME_LEN) );
/*
** Verify that 0 < r' < q and 0 < s' < q
*/
if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
mp_cmp(&r_, &q) >= 0 || mp_cmp(&s_, &q) >= 0)
goto cleanup; /* will return verified == SECFailure */
/*
** FIPS 186-1, Section 6, Step 1
**
** w = (s')**-1 mod q
*/
CHECKOK( mp_invmod(&s_, &q, &w) ); /* w = (s')**-1 mod q */
/*
** FIPS 186-1, Section 6, Step 2
**
** u1 = ((SHA1(M')) * w) mod q
*/
SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */
CHECKOK( mp_mulmod(&u1, &w, &q, &u1) ); /* u1 = u1 * w mod q */
/*
** FIPS 186-1, Section 6, Step 3
**
** u2 = ((r') * w) mod q
*/
CHECKOK( mp_mulmod(&r_, &w, &q, &u2) );
/*
** FIPS 186-1, Section 6, Step 4
**
** v = ((g**u1 * y**u2) mod p) mod q
*/
CHECKOK( mp_exptmod(&g, &u1, &p, &g) ); /* g = g**u1 mod p */
CHECKOK( mp_exptmod(&y, &u2, &p, &y) ); /* y = y**u2 mod p */
CHECKOK( mp_mulmod(&g, &y, &p, &v) ); /* v = g * y mod p */
CHECKOK( mp_mod(&v, &q, &v) ); /* v = v mod q */
/*
** Verification: v == r'
*/
if (mp_cmp(&v, &r_)) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
verified = SECFailure; /* Signature failed to verify. */
} else {
verified = SECSuccess; /* Signature verified. */
}
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
mp_clear(&y);
mp_clear(&r_);
mp_clear(&s_);
mp_clear(&u1);
mp_clear(&u2);
mp_clear(&v);
mp_clear(&w);
if (err) {
translate_mpi_error(err);
}
return verified;
}

View File

@@ -1,977 +0,0 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Elliptic Curve Cryptography library.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#include "blapi.h"
#include "prerr.h"
#include "secerr.h"
#include "secmpi.h"
#include "secitem.h"
#include "ec.h"
#include "GFp_ecl.h"
#include "GF2m_ecl.h"
#ifdef NSS_ENABLE_ECC
/*
* Returns true if pointP is the point at infinity, false otherwise
*/
PRBool
ec_point_at_infinity(SECItem *pointP)
{
int i;
for (i = 1; i < pointP->len; i++) {
if (pointP->data[i] != 0x00) return PR_FALSE;
}
return PR_TRUE;
}
/*
* Computes point addition R = P + Q for the curve whose
* parameters are encoded in params. Two or more of P, Q,
* R may point to the same memory location.
*/
SECStatus
ec_point_add(ECParams *params, SECItem *pointP,
SECItem *pointQ, SECItem *pointR)
{
mp_int Px, Py, Qx, Qy, Rx, Ry;
mp_int irreducible, a;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
int len;
#if EC_DEBUG
int i;
printf("ec_point_add: params [len=%d]:", params->DEREncoding.len);
for (i = 0; i < params->DEREncoding.len; i++)
printf("%02x:", params->DEREncoding.data[i]);
printf("\n");
printf("ec_point_add: pointP [len=%d]:", pointP->len);
for (i = 0; i < pointP->len; i++)
printf("%02x:", pointP->data[i]);
printf("\n");
printf("ec_point_add: pointQ [len=%d]:", pointQ->len);
for (i = 0; i < pointQ->len; i++)
printf("%02x:", pointQ->data[i]);
printf("\n");
#endif
/* NOTE: We only support prime field curves for now */
len = (params->fieldID.size + 7) >> 3;
if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
(pointP->len != (2 * len + 1)) ||
(pointQ->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
(pointQ->len != (2 * len + 1))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
MP_DIGITS(&Px) = 0;
MP_DIGITS(&Py) = 0;
MP_DIGITS(&Qx) = 0;
MP_DIGITS(&Qy) = 0;
MP_DIGITS(&Rx) = 0;
MP_DIGITS(&Ry) = 0;
MP_DIGITS(&irreducible) = 0;
MP_DIGITS(&a) = 0;
CHECK_MPI_OK( mp_init(&Px) );
CHECK_MPI_OK( mp_init(&Py) );
CHECK_MPI_OK( mp_init(&Qx) );
CHECK_MPI_OK( mp_init(&Qy) );
CHECK_MPI_OK( mp_init(&Rx) );
CHECK_MPI_OK( mp_init(&Ry) );
CHECK_MPI_OK( mp_init(&irreducible) );
CHECK_MPI_OK( mp_init(&a) );
/* Initialize Px and Py */
CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len,
(mp_size) len) );
/* Initialize Qx and Qy */
CHECK_MPI_OK( mp_read_unsigned_octets(&Qx, pointQ->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&Qy, pointQ->data + 1 + len,
(mp_size) len) );
/* Set up the curve coefficient */
SECITEM_TO_MPINT( params->curve.a, &a );
/* Compute R = P + Q */
if (params->fieldID.type == ec_field_GFp) {
SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
if (GFp_ec_pt_add(&irreducible, &a, &Px, &Py, &Qx, &Qy,
&Rx, &Ry) != SECSuccess)
goto cleanup;
} else {
SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
if (GF2m_ec_pt_add(&irreducible, &a, &Px, &Py, &Qx, &Qy, &Rx, &Ry)
!= SECSuccess)
goto cleanup;
}
/* Construct the SECItem representation of the result */
pointR->data[0] = EC_POINT_FORM_UNCOMPRESSED;
CHECK_MPI_OK( mp_to_fixlen_octets(&Rx, pointR->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_to_fixlen_octets(&Ry, pointR->data + 1 + len,
(mp_size) len) );
rv = SECSuccess;
#if EC_DEBUG
printf("ec_point_add: pointR [len=%d]:", pointR->len);
for (i = 0; i < pointR->len; i++)
printf("%02x:", pointR->data[i]);
printf("\n");
#endif
cleanup:
mp_clear(&Px);
mp_clear(&Py);
mp_clear(&Qx);
mp_clear(&Qy);
mp_clear(&Rx);
mp_clear(&Ry);
mp_clear(&irreducible);
mp_clear(&a);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
return rv;
}
/*
* Computes scalar point multiplication pointQ = k * pointP for
* the curve whose parameters are encoded in params.
*/
SECStatus
ec_point_mul(ECParams *params, mp_int *k,
SECItem *pointP, SECItem *pointQ)
{
mp_int Px, Py, Qx, Qy;
mp_int irreducible, a, b;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
int len;
#if EC_DEBUG
int i;
char mpstr[256];
printf("ec_point_mul: params [len=%d]:", params->DEREncoding.len);
for (i = 0; i < params->DEREncoding.len; i++)
printf("%02x:", params->DEREncoding.data[i]);
printf("\n");
mp_tohex(k, mpstr);
printf("ec_point_mul: scalar : %s\n", mpstr);
mp_todecimal(k, mpstr);
printf("ec_point_mul: scalar : %s (dec)\n", mpstr);
printf("ec_point_mul: pointP [len=%d]:", pointP->len);
for (i = 0; i < pointP->len; i++)
printf("%02x:", pointP->data[i]);
printf("\n");
#endif
/* NOTE: We only support prime field curves for now */
len = (params->fieldID.size + 7) >> 3;
if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
(pointP->len != (2 * len + 1))) {
return SECFailure;
};
MP_DIGITS(&Px) = 0;
MP_DIGITS(&Py) = 0;
MP_DIGITS(&Qx) = 0;
MP_DIGITS(&Qy) = 0;
MP_DIGITS(&irreducible) = 0;
MP_DIGITS(&a) = 0;
MP_DIGITS(&b) = 0;
CHECK_MPI_OK( mp_init(&Px) );
CHECK_MPI_OK( mp_init(&Py) );
CHECK_MPI_OK( mp_init(&Qx) );
CHECK_MPI_OK( mp_init(&Qy) );
CHECK_MPI_OK( mp_init(&irreducible) );
CHECK_MPI_OK( mp_init(&a) );
CHECK_MPI_OK( mp_init(&b) );
/* Initialize Px and Py */
CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len,
(mp_size) len) );
/* Set up mp_ints containing the curve coefficients */
SECITEM_TO_MPINT( params->curve.a, &a );
SECITEM_TO_MPINT( params->curve.b, &b );
/* Compute Q = k * P */
if (params->fieldID.type == ec_field_GFp) {
SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
if (GFp_ec_pt_mul(&irreducible, &a, &b, &Px, &Py, k, &Qx, &Qy)
!= SECSuccess)
goto cleanup;
} else {
SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
if (GF2m_ec_pt_mul(&irreducible, &a, &b, &Px, &Py, k, &Qx, &Qy)
!= SECSuccess) {
goto cleanup;
}
}
/* Construct the SECItem representation of point Q */
pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
(mp_size) len) );
rv = SECSuccess;
#if EC_DEBUG
printf("ec_point_mul: pointQ [len=%d]:", pointQ->len);
for (i = 0; i < pointQ->len; i++)
printf("%02x:", pointQ->data[i]);
printf("\n");
#endif
cleanup:
mp_clear(&Px);
mp_clear(&Py);
mp_clear(&Qx);
mp_clear(&Qy);
mp_clear(&irreducible);
mp_clear(&a);
mp_clear(&b);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
return rv;
}
static unsigned char bitmask[] = {
0xff, 0x7f, 0x3f, 0x1f,
0x0f, 0x07, 0x03, 0x01
};
#endif /* NSS_ENABLE_ECC */
/* Generates a new EC key pair. The private key is a supplied
* random value (in seed) and the public key is the result of
* performing a scalar point multiplication of that value with
* the curve's base point.
*/
SECStatus
EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
const unsigned char *seed, int seedlen)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
PRArenaPool *arena;
ECPrivateKey *key;
mp_int k;
mp_err err = MP_OKAY;
int len;
#if EC_DEBUG
printf("EC_NewKeyFromSeed called\n");
#endif
if (!ecParams || !privKey || !seed || (seedlen < 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Initialize an arena for the EC key. */
if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
return SECFailure;
key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
if (!key) {
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
/* Copy all of the fields from the ECParams argument to the
* ECParams structure within the private key.
*/
key->ecParams.arena = arena;
key->ecParams.type = ecParams->type;
key->ecParams.fieldID.size = ecParams->fieldID.size;
key->ecParams.fieldID.type = ecParams->fieldID.type;
if (ecParams->fieldID.type == ec_field_GFp) {
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
&ecParams->fieldID.u.prime));
} else {
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
&ecParams->fieldID.u.poly));
}
key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
&ecParams->curve.a));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
&ecParams->curve.b));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
&ecParams->curve.seed));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
&ecParams->base));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
&ecParams->order));
key->ecParams.cofactor = ecParams->cofactor;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
&ecParams->DEREncoding));
len = (ecParams->fieldID.size + 7) >> 3;
SECITEM_AllocItem(arena, &key->privateValue, len);
SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1);
/* Copy private key */
if (seedlen >= len) {
memcpy(key->privateValue.data, seed, len);
} else {
memset(key->privateValue.data, 0, (len - seedlen));
memcpy(key->privateValue.data + (len - seedlen), seed, seedlen);
}
/* Compute corresponding public key */
MP_DIGITS(&k) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
(mp_size) len) );
rv = ec_point_mul(ecParams, &k, &(ecParams->base), &(key->publicValue));
if (rv != SECSuccess) goto cleanup;
*privKey = key;
cleanup:
mp_clear(&k);
if (rv)
PORT_FreeArena(arena, PR_TRUE);
#if EC_DEBUG
printf("EC_NewKeyFromSeed returning %s\n",
(rv == SECSuccess) ? "success" : "failure");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/* Generates a new EC key pair. The private key is a random value and
* the public key is the result of performing a scalar point multiplication
* of that value with the curve's base point.
*/
SECStatus
EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
int len;
unsigned char *seed;
if (!ecParams || !privKey) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Generate random private key */
len = (ecParams->fieldID.size + 7) >> 3;
if ((seed = PORT_Alloc(len)) == NULL) goto cleanup;
if (RNG_GenerateGlobalRandomBytes(seed, len) != SECSuccess) goto cleanup;
/* Fit private key to the field size */
seed[0] &= bitmask[len * 8 - ecParams->fieldID.size];
rv = EC_NewKeyFromSeed(ecParams, privKey, seed, len);
cleanup:
if (!seed) {
PORT_ZFree(seed, len);
}
#if EC_DEBUG
printf("EC_NewKey returning %s\n",
(rv == SECSuccess) ? "success" : "failure");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/* Validates an EC public key as described in Section 5.2.2 of
* X9.63. The ECDH primitive when used without the cofactor does
* not address small subgroup attacks, which may occur when the
* public key is not valid. These attacks can be prevented by
* validating the public key before using ECDH.
*/
SECStatus
EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
{
#ifdef NSS_ENABLE_ECC
if (!ecParams || !publicValue) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* XXX Add actual checks here. */
return SECSuccess;
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
return SECFailure;
#endif /* NSS_ENABLE_ECC */
}
/*
** Performs an ECDH key derivation by computing the scalar point
** multiplication of privateValue and publicValue (with or without the
** cofactor) and returns the x-coordinate of the resulting elliptic
** curve point in derived secret. If successful, derivedSecret->data
** is set to the address of the newly allocated buffer containing the
** derived secret, and derivedSecret->len is the size of the secret
** produced. It is the caller's responsibility to free the allocated
** buffer containing the derived secret.
*/
SECStatus
ECDH_Derive(SECItem *publicValue,
ECParams *ecParams,
SECItem *privateValue,
PRBool withCofactor,
SECItem *derivedSecret)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
unsigned int len = 0;
SECItem pointQ = {siBuffer, NULL, 0};
mp_int k; /* to hold the private value */
mp_int cofactor;
mp_err err = MP_OKAY;
#if EC_DEBUG
int i;
#endif
if (!publicValue || !ecParams || !privateValue ||
!derivedSecret) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
memset(derivedSecret, 0, sizeof *derivedSecret);
len = (ecParams->fieldID.size + 7) >> 3;
pointQ.len = 2*len + 1;
if ((pointQ.data = PORT_Alloc(2*len + 1)) == NULL) goto cleanup;
MP_DIGITS(&k) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
(mp_size) privateValue->len) );
if (withCofactor && (ecParams->cofactor != 1)) {
/* multiply k with the cofactor */
MP_DIGITS(&cofactor) = 0;
CHECK_MPI_OK( mp_init(&cofactor) );
mp_set(&cofactor, ecParams->cofactor);
CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
}
/* Multiply our private key and peer's public point */
if ((ec_point_mul(ecParams, &k, publicValue, &pointQ) != SECSuccess) ||
ec_point_at_infinity(&pointQ))
goto cleanup;
/* Allocate memory for the derived secret and copy
* the x co-ordinate of pointQ into it.
*/
SECITEM_AllocItem(NULL, derivedSecret, len);
memcpy(derivedSecret->data, pointQ.data + 1, len);
rv = SECSuccess;
#if EC_DEBUG
printf("derived_secret:\n");
for (i = 0; i < derivedSecret->len; i++)
printf("%02x:", derivedSecret->data[i]);
printf("\n");
#endif
cleanup:
mp_clear(&k);
if (pointQ.data) {
PORT_ZFree(pointQ.data, 2*len + 1);
}
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/* Computes the ECDSA signature (a concatenation of two values r and s)
* on the digest using the given key and the random value kb (used in
* computing s).
*/
SECStatus
ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
const SECItem *digest, const unsigned char *kb, const int kblen)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
mp_int x1;
mp_int d, k; /* private key, random integer */
mp_int r, s; /* tuple (r, s) is the signature */
mp_int n;
mp_err err = MP_OKAY;
ECParams *ecParams = NULL;
SECItem kGpoint = { siBuffer, NULL, 0};
int len = 0;
#if EC_DEBUG
char mpstr[256];
#endif
/* Check args */
if (!key || !signature || !digest || !kb || (kblen < 0) ||
(digest->len != SHA1_LENGTH)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
ecParams = &(key->ecParams);
len = (ecParams->fieldID.size + 7) >> 3;
if (signature->len < 2*len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
/* Initialize MPI integers. */
MP_DIGITS(&x1) = 0;
MP_DIGITS(&d) = 0;
MP_DIGITS(&k) = 0;
MP_DIGITS(&r) = 0;
MP_DIGITS(&s) = 0;
MP_DIGITS(&n) = 0;
CHECK_MPI_OK( mp_init(&x1) );
CHECK_MPI_OK( mp_init(&d) );
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&r) );
CHECK_MPI_OK( mp_init(&s) );
CHECK_MPI_OK( mp_init(&n) );
SECITEM_TO_MPINT( ecParams->order, &n );
SECITEM_TO_MPINT( key->privateValue, &d );
CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
/* Make sure k is in the interval [1, n-1] */
if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
goto cleanup;
}
/*
** ANSI X9.62, Section 5.3.2, Step 2
**
** Compute kG
*/
kGpoint.len = 2*len + 1;
kGpoint.data = PORT_Alloc(2*len + 1);
if ((kGpoint.data == NULL) ||
(ec_point_mul(ecParams, &k, &(ecParams->base), &kGpoint)
!= SECSuccess))
goto cleanup;
/*
** ANSI X9.62, Section 5.3.3, Step 1
**
** Extract the x co-ordinate of kG into x1
*/
CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
(mp_size) len) );
/*
** ANSI X9.62, Section 5.3.3, Step 2
**
** r = x1 mod n NOTE: n is the order of the curve
*/
CHECK_MPI_OK( mp_mod(&x1, &n, &r) );
/*
** ANSI X9.62, Section 5.3.3, Step 3
**
** verify r != 0
*/
if (mp_cmp_z(&r) == 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
goto cleanup;
}
/*
** ANSI X9.62, Section 5.3.3, Step 4
**
** s = (k**-1 * (SHA1(M) + d*r)) mod n
*/
SECITEM_TO_MPINT(*digest, &s); /* s = SHA1(M) */
#if EC_DEBUG
mp_todecimal(&n, mpstr);
printf("n : %s (dec)\n", mpstr);
mp_todecimal(&d, mpstr);
printf("d : %s (dec)\n", mpstr);
mp_tohex(&x1, mpstr);
printf("x1: %s\n", mpstr);
mp_todecimal(&s, mpstr);
printf("digest: %s (decimal)\n", mpstr);
mp_todecimal(&r, mpstr);
printf("r : %s (dec)\n", mpstr);
#endif
CHECK_MPI_OK( mp_invmod(&k, &n, &k) ); /* k = k**-1 mod n */
CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) ); /* d = d * r mod n */
CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) ); /* s = s + d mod n */
CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) ); /* s = s * k mod n */
#if EC_DEBUG
mp_todecimal(&s, mpstr);
printf("s : %s (dec)\n", mpstr);
#endif
/*
** ANSI X9.62, Section 5.3.3, Step 5
**
** verify s != 0
*/
if (mp_cmp_z(&s) == 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
goto cleanup;
}
/*
**
** Signature is tuple (r, s)
*/
CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, len) );
CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + len, len) );
signature->len = 2*len;
rv = SECSuccess;
err = MP_OKAY;
cleanup:
mp_clear(&x1);
mp_clear(&d);
mp_clear(&k);
mp_clear(&r);
mp_clear(&s);
mp_clear(&n);
if (kGpoint.data) {
PORT_ZFree(kGpoint.data, 2*len + 1);
}
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
#if EC_DEBUG
printf("ECDSA signing with seed %s\n",
(rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/*
** Computes the ECDSA signature on the digest using the given key
** and a random seed.
*/
SECStatus
ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
int prerr = 0;
int n = (key->ecParams.fieldID.size + 7) >> 3;
unsigned char mask = bitmask[n * 8 - key->ecParams.fieldID.size];
unsigned char *kseed = NULL;
/* Generate random seed of appropriate size as dictated
* by field size.
*/
if ((kseed = PORT_Alloc(n)) == NULL) return SECFailure;
do {
if (RNG_GenerateGlobalRandomBytes(kseed, n) != SECSuccess)
goto cleanup;
*kseed &= mask;
rv = ECDSA_SignDigestWithSeed(key, signature, digest, kseed, n);
if (rv) prerr = PORT_GetError();
} while ((rv != SECSuccess) && (prerr == SEC_ERROR_NEED_RANDOM));
cleanup:
if (kseed) PORT_ZFree(kseed, n);
#if EC_DEBUG
printf("ECDSA signing %s\n",
(rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/*
** Checks the signature on the given digest using the key provided.
*/
SECStatus
ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
const SECItem *digest)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
mp_int r_, s_; /* tuple (r', s') is received signature) */
mp_int c, u1, u2, v; /* intermediate values used in verification */
mp_int x1, y1;
mp_int x2, y2;
mp_int n;
mp_err err = MP_OKAY;
PRArenaPool *arena = NULL;
ECParams *ecParams = NULL;
SECItem pointA = { siBuffer, NULL, 0 };
SECItem pointB = { siBuffer, NULL, 0 };
SECItem pointC = { siBuffer, NULL, 0 };
int len;
#if EC_DEBUG
char mpstr[256];
printf("ECDSA verification called\n");
#endif
/* Check args */
if (!key || !signature || !digest ||
(digest->len != SHA1_LENGTH)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
ecParams = &(key->ecParams);
len = (ecParams->fieldID.size + 7) >> 3;
if (signature->len < 2*len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
/* Initialize an arena for pointA, pointB and pointC */
if ((arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)) == NULL)
goto cleanup;
SECITEM_AllocItem(arena, &pointA, 2*len + 1);
SECITEM_AllocItem(arena, &pointB, 2*len + 1);
SECITEM_AllocItem(arena, &pointC, 2*len + 1);
if (pointA.data == NULL || pointB.data == NULL || pointC.data == NULL)
goto cleanup;
/* Initialize MPI integers. */
MP_DIGITS(&r_) = 0;
MP_DIGITS(&s_) = 0;
MP_DIGITS(&c) = 0;
MP_DIGITS(&u1) = 0;
MP_DIGITS(&u2) = 0;
MP_DIGITS(&x1) = 0;
MP_DIGITS(&y1) = 0;
MP_DIGITS(&x2) = 0;
MP_DIGITS(&y2) = 0;
MP_DIGITS(&v) = 0;
MP_DIGITS(&n) = 0;
CHECK_MPI_OK( mp_init(&r_) );
CHECK_MPI_OK( mp_init(&s_) );
CHECK_MPI_OK( mp_init(&c) );
CHECK_MPI_OK( mp_init(&u1) );
CHECK_MPI_OK( mp_init(&u2) );
CHECK_MPI_OK( mp_init(&x1) );
CHECK_MPI_OK( mp_init(&y1) );
CHECK_MPI_OK( mp_init(&x2) );
CHECK_MPI_OK( mp_init(&y2) );
CHECK_MPI_OK( mp_init(&v) );
CHECK_MPI_OK( mp_init(&n) );
/*
** Convert received signature (r', s') into MPI integers.
*/
CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + len, len) );
/*
** ANSI X9.62, Section 5.4.2, Steps 1 and 2
**
** Verify that 0 < r' < n and 0 < s' < n
*/
SECITEM_TO_MPINT(ecParams->order, &n);
if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0)
goto cleanup; /* will return rv == SECFailure */
/*
** ANSI X9.62, Section 5.4.2, Step 3
**
** c = (s')**-1 mod n
*/
CHECK_MPI_OK( mp_invmod(&s_, &n, &c) ); /* c = (s')**-1 mod n */
/*
** ANSI X9.62, Section 5.4.2, Step 4
**
** u1 = ((SHA1(M')) * c) mod n
*/
SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */
#if EC_DEBUG
mp_todecimal(&r_, mpstr);
printf("r_: %s (dec)\n", mpstr);
mp_todecimal(&s_, mpstr);
printf("s_: %s (dec)\n", mpstr);
mp_todecimal(&c, mpstr);
printf("c : %s (dec)\n", mpstr);
mp_todecimal(&u1, mpstr);
printf("digest: %s (dec)\n", mpstr);
#endif
CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) ); /* u1 = u1 * c mod n */
/*
** ANSI X9.62, Section 5.4.2, Step 4
**
** u2 = ((r') * c) mod n
*/
CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );
/*
** ANSI X9.62, Section 5.4.3, Step 1
**
** Compute u1*G + u2*Q
** Here, A = u1.G B = u2.Q and C = A + B
** If the result, C, is the point at infinity, reject the signature
*/
if ((ec_point_mul(ecParams, &u1, &ecParams->base, &pointA)
== SECFailure) ||
(ec_point_mul(ecParams, &u2, &key->publicValue, &pointB)
== SECFailure) ||
(ec_point_add(ecParams, &pointA, &pointB, &pointC) == SECFailure) ||
ec_point_at_infinity(&pointC)) {
rv = SECFailure;
goto cleanup;
}
CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, len) );
/*
** ANSI X9.62, Section 5.4.4, Step 2
**
** v = x1 mod n
*/
CHECK_MPI_OK( mp_mod(&x1, &n, &v) );
/*
** ANSI X9.62, Section 5.4.4, Step 3
**
** Verification: v == r'
*/
if (mp_cmp(&v, &r_)) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
rv = SECFailure; /* Signature failed to verify. */
} else {
rv = SECSuccess; /* Signature verified. */
}
#if EC_DEBUG
mp_todecimal(&u1, mpstr);
printf("u1: %s (dec)\n", mpstr);
mp_todecimal(&u2, mpstr);
printf("u2: %s (dec)\n", mpstr);
mp_tohex(&x1, mpstr);
printf("x1: %s\n", mpstr);
mp_todecimal(&v, mpstr);
printf("v : %s (dec)\n", mpstr);
#endif
cleanup:
mp_clear(&r_);
mp_clear(&s_);
mp_clear(&c);
mp_clear(&u1);
mp_clear(&u2);
mp_clear(&x1);
mp_clear(&y1);
mp_clear(&x2);
mp_clear(&y2);
mp_clear(&v);
mp_clear(&n);
if (arena) PORT_FreeArena(arena, PR_TRUE);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
#if EC_DEBUG
printf("ECDSA verification %s\n",
(rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}

View File

@@ -1,50 +0,0 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Elliptic Curve Cryptography library.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifndef __ec_h_
#define __ec_h_
#define EC_DEBUG 0
#define EC_POINT_FORM_COMPRESSED_Y0 0x02
#define EC_POINT_FORM_COMPRESSED_Y1 0x03
#define EC_POINT_FORM_UNCOMPRESSED 0x04
#define EC_POINT_FORM_HYBRID_Y0 0x06
#define EC_POINT_FORM_HYBRID_Y1 0x07
#define ANSI_X962_CURVE_OID_TOTAL_LEN 10
#define SECG_CURVE_OID_TOTAL_LEN 7
#endif /* __ec_h_ */

View File

@@ -1,120 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include <stdio.h>
#include <stdlib.h>
#include <plstr.h>
#include "aglobal.h"
#include "bsafe.h"
#include "secport.h"
void CALL_CONV T_memset (p, c, count)
POINTER p;
int c;
unsigned int count;
{
if (count >= 0)
memset(p, c, count);
}
void CALL_CONV T_memcpy (d, s, count)
POINTER d, s;
unsigned int count;
{
if (count >= 0)
memcpy(d, s, count);
}
void CALL_CONV T_memmove (d, s, count)
POINTER d, s;
unsigned int count;
{
if (count >= 0)
PORT_Memmove(d, s, count);
}
int CALL_CONV T_memcmp (s1, s2, count)
POINTER s1, s2;
unsigned int count;
{
if (count == 0)
return (0);
else
return(memcmp(s1, s2, count));
}
POINTER CALL_CONV T_malloc (size)
unsigned int size;
{
return((POINTER)PORT_Alloc(size == 0 ? 1 : size));
}
POINTER CALL_CONV T_realloc (p, size)
POINTER p;
unsigned int size;
{
POINTER result;
if (p == NULL_PTR)
return (T_malloc(size));
if ((result = (POINTER)PORT_Realloc(p, size == 0 ? 1 : size)) == NULL_PTR)
PORT_Free(p);
return (result);
}
void CALL_CONV T_free (p)
POINTER p;
{
if (p != NULL_PTR)
PORT_Free(p);
}
unsigned int CALL_CONV T_strlen(p)
char *p;
{
return PL_strlen(p);
}
void CALL_CONV T_strcpy(dest, src)
char *dest;
char *src;
{
PL_strcpy(dest, src);
}
int CALL_CONV T_strcmp (a, b)
char *a, *b;
{
return (PL_strcmp (a, b));
}

View File

@@ -1,196 +0,0 @@
/*
* ldvector.c - platform dependent DSO containing freebl implementation.
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: ldvector.c,v 1.6 2003-02-27 01:31:13 nelsonb%netscape.com Exp $
*/
#include "loader.h"
static const struct FREEBLVectorStr vector = {
sizeof vector,
FREEBL_VERSION,
RSA_NewKey,
RSA_PublicKeyOp,
RSA_PrivateKeyOp,
DSA_NewKey,
DSA_SignDigest,
DSA_VerifyDigest,
DSA_NewKeyFromSeed,
DSA_SignDigestWithSeed,
DH_GenParam,
DH_NewKey,
DH_Derive,
KEA_Derive,
KEA_Verify,
RC4_CreateContext,
RC4_DestroyContext,
RC4_Encrypt,
RC4_Decrypt,
RC2_CreateContext,
RC2_DestroyContext,
RC2_Encrypt,
RC2_Decrypt,
RC5_CreateContext,
RC5_DestroyContext,
RC5_Encrypt,
RC5_Decrypt,
DES_CreateContext,
DES_DestroyContext,
DES_Encrypt,
DES_Decrypt,
AES_CreateContext,
AES_DestroyContext,
AES_Encrypt,
AES_Decrypt,
MD5_Hash,
MD5_HashBuf,
MD5_NewContext,
MD5_DestroyContext,
MD5_Begin,
MD5_Update,
MD5_End,
MD5_FlattenSize,
MD5_Flatten,
MD5_Resurrect,
MD5_TraceState,
MD2_Hash,
MD2_NewContext,
MD2_DestroyContext,
MD2_Begin,
MD2_Update,
MD2_End,
MD2_FlattenSize,
MD2_Flatten,
MD2_Resurrect,
SHA1_Hash,
SHA1_HashBuf,
SHA1_NewContext,
SHA1_DestroyContext,
SHA1_Begin,
SHA1_Update,
SHA1_End,
SHA1_TraceState,
SHA1_FlattenSize,
SHA1_Flatten,
SHA1_Resurrect,
RNG_RNGInit,
RNG_RandomUpdate,
RNG_GenerateGlobalRandomBytes,
RNG_RNGShutdown,
PQG_ParamGen,
PQG_ParamGenSeedLen,
PQG_VerifyParams,
/* End of Version 3.001. */
RSA_PrivateKeyOpDoubleChecked,
RSA_PrivateKeyCheck,
BL_Cleanup,
/* End of Version 3.002. */
SHA256_NewContext,
SHA256_DestroyContext,
SHA256_Begin,
SHA256_Update,
SHA256_End,
SHA256_HashBuf,
SHA256_Hash,
SHA256_TraceState,
SHA256_FlattenSize,
SHA256_Flatten,
SHA256_Resurrect,
SHA512_NewContext,
SHA512_DestroyContext,
SHA512_Begin,
SHA512_Update,
SHA512_End,
SHA512_HashBuf,
SHA512_Hash,
SHA512_TraceState,
SHA512_FlattenSize,
SHA512_Flatten,
SHA512_Resurrect,
SHA384_NewContext,
SHA384_DestroyContext,
SHA384_Begin,
SHA384_Update,
SHA384_End,
SHA384_HashBuf,
SHA384_Hash,
SHA384_TraceState,
SHA384_FlattenSize,
SHA384_Flatten,
SHA384_Resurrect,
/* End of Version 3.003. */
AESKeyWrap_CreateContext,
AESKeyWrap_DestroyContext,
AESKeyWrap_Encrypt,
AESKeyWrap_Decrypt,
/* End of Version 3.004. */
BLAPI_SHVerify,
BLAPI_VerifySelf,
/* End of Version 3.005. */
EC_NewKey,
EC_NewKeyFromSeed,
EC_ValidatePublicKey,
ECDH_Derive,
ECDSA_SignDigest,
ECDSA_VerifyDigest,
ECDSA_SignDigestWithSeed,
/* End of Version 3.006. */
};
const FREEBLVector *
FREEBL_GetVector(void)
{
return &vector;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,386 +0,0 @@
/*
* loader.h - load platform dependent DSO containing freebl implementation.
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: loader.h,v 1.9 2003-02-27 01:31:14 nelsonb%netscape.com Exp $
*/
#ifndef _LOADER_H_
#define _LOADER_H_ 1
#include "blapi.h"
#define FREEBL_VERSION 0x0306
struct FREEBLVectorStr {
unsigned short length; /* of this struct in bytes */
unsigned short version; /* of this struct. */
RSAPrivateKey * (* p_RSA_NewKey)(int keySizeInBits,
SECItem * publicExponent);
SECStatus (* p_RSA_PublicKeyOp) (RSAPublicKey * key,
unsigned char * output,
const unsigned char * input);
SECStatus (* p_RSA_PrivateKeyOp)(RSAPrivateKey * key,
unsigned char * output,
const unsigned char * input);
SECStatus (* p_DSA_NewKey)(const PQGParams * params,
DSAPrivateKey ** privKey);
SECStatus (* p_DSA_SignDigest)(DSAPrivateKey * key,
SECItem * signature,
const SECItem * digest);
SECStatus (* p_DSA_VerifyDigest)(DSAPublicKey * key,
const SECItem * signature,
const SECItem * digest);
SECStatus (* p_DSA_NewKeyFromSeed)(const PQGParams *params,
const unsigned char * seed,
DSAPrivateKey **privKey);
SECStatus (* p_DSA_SignDigestWithSeed)(DSAPrivateKey * key,
SECItem * signature,
const SECItem * digest,
const unsigned char * seed);
SECStatus (* p_DH_GenParam)(int primeLen, DHParams ** params);
SECStatus (* p_DH_NewKey)(DHParams * params,
DHPrivateKey ** privKey);
SECStatus (* p_DH_Derive)(SECItem * publicValue,
SECItem * prime,
SECItem * privateValue,
SECItem * derivedSecret,
unsigned int maxOutBytes);
SECStatus (* p_KEA_Derive)(SECItem *prime,
SECItem *public1,
SECItem *public2,
SECItem *private1,
SECItem *private2,
SECItem *derivedSecret);
PRBool (* p_KEA_Verify)(SECItem *Y, SECItem *prime, SECItem *subPrime);
RC4Context * (* p_RC4_CreateContext)(const unsigned char *key, int len);
void (* p_RC4_DestroyContext)(RC4Context *cx, PRBool freeit);
SECStatus (* p_RC4_Encrypt)(RC4Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
SECStatus (* p_RC4_Decrypt)(RC4Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
RC2Context * (* p_RC2_CreateContext)(const unsigned char *key,
unsigned int len, const unsigned char *iv,
int mode, unsigned effectiveKeyLen);
void (* p_RC2_DestroyContext)(RC2Context *cx, PRBool freeit);
SECStatus (* p_RC2_Encrypt)(RC2Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
SECStatus (* p_RC2_Decrypt)(RC2Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
RC5Context *(* p_RC5_CreateContext)(const SECItem *key, unsigned int rounds,
unsigned int wordSize, const unsigned char *iv, int mode);
void (* p_RC5_DestroyContext)(RC5Context *cx, PRBool freeit);
SECStatus (* p_RC5_Encrypt)(RC5Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
SECStatus (* p_RC5_Decrypt)(RC5Context *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
DESContext *(* p_DES_CreateContext)(const unsigned char *key,
const unsigned char *iv,
int mode, PRBool encrypt);
void (* p_DES_DestroyContext)(DESContext *cx, PRBool freeit);
SECStatus (* p_DES_Encrypt)(DESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
SECStatus (* p_DES_Decrypt)(DESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
AESContext * (* p_AES_CreateContext)(const unsigned char *key,
const unsigned char *iv,
int mode, int encrypt, unsigned int keylen,
unsigned int blocklen);
void (* p_AES_DestroyContext)(AESContext *cx, PRBool freeit);
SECStatus (* p_AES_Encrypt)(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
SECStatus (* p_AES_Decrypt)(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
SECStatus (* p_MD5_Hash)(unsigned char *dest, const char *src);
SECStatus (* p_MD5_HashBuf)(unsigned char *dest, const unsigned char *src,
uint32 src_length);
MD5Context *(* p_MD5_NewContext)(void);
void (* p_MD5_DestroyContext)(MD5Context *cx, PRBool freeit);
void (* p_MD5_Begin)(MD5Context *cx);
void (* p_MD5_Update)(MD5Context *cx,
const unsigned char *input, unsigned int inputLen);
void (* p_MD5_End)(MD5Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen);
unsigned int (* p_MD5_FlattenSize)(MD5Context *cx);
SECStatus (* p_MD5_Flatten)(MD5Context *cx,unsigned char *space);
MD5Context * (* p_MD5_Resurrect)(unsigned char *space, void *arg);
void (* p_MD5_TraceState)(MD5Context *cx);
SECStatus (* p_MD2_Hash)(unsigned char *dest, const char *src);
MD2Context *(* p_MD2_NewContext)(void);
void (* p_MD2_DestroyContext)(MD2Context *cx, PRBool freeit);
void (* p_MD2_Begin)(MD2Context *cx);
void (* p_MD2_Update)(MD2Context *cx,
const unsigned char *input, unsigned int inputLen);
void (* p_MD2_End)(MD2Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen);
unsigned int (* p_MD2_FlattenSize)(MD2Context *cx);
SECStatus (* p_MD2_Flatten)(MD2Context *cx,unsigned char *space);
MD2Context * (* p_MD2_Resurrect)(unsigned char *space, void *arg);
SECStatus (* p_SHA1_Hash)(unsigned char *dest, const char *src);
SECStatus (* p_SHA1_HashBuf)(unsigned char *dest, const unsigned char *src,
uint32 src_length);
SHA1Context *(* p_SHA1_NewContext)(void);
void (* p_SHA1_DestroyContext)(SHA1Context *cx, PRBool freeit);
void (* p_SHA1_Begin)(SHA1Context *cx);
void (* p_SHA1_Update)(SHA1Context *cx, const unsigned char *input,
unsigned int inputLen);
void (* p_SHA1_End)(SHA1Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen);
void (* p_SHA1_TraceState)(SHA1Context *cx);
unsigned int (* p_SHA1_FlattenSize)(SHA1Context *cx);
SECStatus (* p_SHA1_Flatten)(SHA1Context *cx,unsigned char *space);
SHA1Context * (* p_SHA1_Resurrect)(unsigned char *space, void *arg);
SECStatus (* p_RNG_RNGInit)(void);
SECStatus (* p_RNG_RandomUpdate)(const void *data, size_t bytes);
SECStatus (* p_RNG_GenerateGlobalRandomBytes)(void *dest, size_t len);
void (* p_RNG_RNGShutdown)(void);
SECStatus (* p_PQG_ParamGen)(unsigned int j, PQGParams **pParams,
PQGVerify **pVfy);
SECStatus (* p_PQG_ParamGenSeedLen)( unsigned int j, unsigned int seedBytes,
PQGParams **pParams, PQGVerify **pVfy);
SECStatus (* p_PQG_VerifyParams)(const PQGParams *params,
const PQGVerify *vfy, SECStatus *result);
/* Version 3.001 came to here */
SECStatus (* p_RSA_PrivateKeyOpDoubleChecked)(RSAPrivateKey *key,
unsigned char *output,
const unsigned char *input);
SECStatus (* p_RSA_PrivateKeyCheck)(RSAPrivateKey *key);
void (* p_BL_Cleanup)(void);
/* Version 3.002 came to here */
SHA256Context *(* p_SHA256_NewContext)(void);
void (* p_SHA256_DestroyContext)(SHA256Context *cx, PRBool freeit);
void (* p_SHA256_Begin)(SHA256Context *cx);
void (* p_SHA256_Update)(SHA256Context *cx, const unsigned char *input,
unsigned int inputLen);
void (* p_SHA256_End)(SHA256Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen);
SECStatus (* p_SHA256_HashBuf)(unsigned char *dest, const unsigned char *src,
uint32 src_length);
SECStatus (* p_SHA256_Hash)(unsigned char *dest, const char *src);
void (* p_SHA256_TraceState)(SHA256Context *cx);
unsigned int (* p_SHA256_FlattenSize)(SHA256Context *cx);
SECStatus (* p_SHA256_Flatten)(SHA256Context *cx,unsigned char *space);
SHA256Context * (* p_SHA256_Resurrect)(unsigned char *space, void *arg);
SHA512Context *(* p_SHA512_NewContext)(void);
void (* p_SHA512_DestroyContext)(SHA512Context *cx, PRBool freeit);
void (* p_SHA512_Begin)(SHA512Context *cx);
void (* p_SHA512_Update)(SHA512Context *cx, const unsigned char *input,
unsigned int inputLen);
void (* p_SHA512_End)(SHA512Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen);
SECStatus (* p_SHA512_HashBuf)(unsigned char *dest, const unsigned char *src,
uint32 src_length);
SECStatus (* p_SHA512_Hash)(unsigned char *dest, const char *src);
void (* p_SHA512_TraceState)(SHA512Context *cx);
unsigned int (* p_SHA512_FlattenSize)(SHA512Context *cx);
SECStatus (* p_SHA512_Flatten)(SHA512Context *cx,unsigned char *space);
SHA512Context * (* p_SHA512_Resurrect)(unsigned char *space, void *arg);
SHA384Context *(* p_SHA384_NewContext)(void);
void (* p_SHA384_DestroyContext)(SHA384Context *cx, PRBool freeit);
void (* p_SHA384_Begin)(SHA384Context *cx);
void (* p_SHA384_Update)(SHA384Context *cx, const unsigned char *input,
unsigned int inputLen);
void (* p_SHA384_End)(SHA384Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen);
SECStatus (* p_SHA384_HashBuf)(unsigned char *dest, const unsigned char *src,
uint32 src_length);
SECStatus (* p_SHA384_Hash)(unsigned char *dest, const char *src);
void (* p_SHA384_TraceState)(SHA384Context *cx);
unsigned int (* p_SHA384_FlattenSize)(SHA384Context *cx);
SECStatus (* p_SHA384_Flatten)(SHA384Context *cx,unsigned char *space);
SHA384Context * (* p_SHA384_Resurrect)(unsigned char *space, void *arg);
/* Version 3.003 came to here */
AESKeyWrapContext * (* p_AESKeyWrap_CreateContext)(const unsigned char *key,
const unsigned char *iv, int encrypt, unsigned int keylen);
void (* p_AESKeyWrap_DestroyContext)(AESKeyWrapContext *cx, PRBool freeit);
SECStatus (* p_AESKeyWrap_Encrypt)(AESKeyWrapContext *cx,
unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
SECStatus (* p_AESKeyWrap_Decrypt)(AESKeyWrapContext *cx,
unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
/* Version 3.004 came to here */
PRBool (*p_BLAPI_SHVerify)(const char *name, PRFuncPtr addr);
PRBool (*p_BLAPI_VerifySelf)(const char *name);
/* Version 3.005 came to here */
SECStatus (* p_EC_NewKey)(ECParams * params,
ECPrivateKey ** privKey);
SECStatus (* p_EC_NewKeyFromSeed)(ECParams * params,
ECPrivateKey ** privKey,
const unsigned char * seed,
int seedlen);
SECStatus (* p_EC_ValidatePublicKey)(ECParams * params,
SECItem * publicValue);
SECStatus (* p_ECDH_Derive)(SECItem * publicValue,
ECParams * params,
SECItem * privateValue,
PRBool withCofactor,
SECItem * derivedSecret);
SECStatus (* p_ECDSA_SignDigest)(ECPrivateKey * key,
SECItem * signature,
const SECItem * digest);
SECStatus (* p_ECDSA_VerifyDigest)(ECPublicKey * key,
const SECItem * signature,
const SECItem * digest);
SECStatus (* p_ECDSA_SignDigestWithSeed)(ECPrivateKey * key,
SECItem * signature,
const SECItem * digest,
const unsigned char * seed,
const int seedlen);
/* Version 3.006 came to here */
};
typedef struct FREEBLVectorStr FREEBLVector;
SEC_BEGIN_PROTOS
typedef const FREEBLVector * FREEBLGetVectorFn(void);
extern FREEBLGetVectorFn FREEBL_GetVector;
SEC_END_PROTOS
#endif

View File

@@ -1,315 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifdef notdef
#include "xp_core.h"
#include "xp_file.h"
#endif
#include "secrng.h"
#include "mcom_db.h"
#ifdef XP_MAC
#include <Events.h>
#include <OSUtils.h>
#include <QDOffscreen.h>
#include <PPCToolbox.h>
#include <Processes.h>
#include <LowMem.h>
#include <Scrap.h>
/* Static prototypes */
static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen);
void FE_ReadScreen();
static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen)
{
union endianness {
int32 i;
char c[4];
} u;
if (srclen <= dstlen) {
memcpy(dst, src, srclen);
return srclen;
}
u.i = 0x01020304;
if (u.c[0] == 0x01) {
/* big-endian case */
memcpy(dst, (char*)src + (srclen - dstlen), dstlen);
} else {
/* little-endian case */
memcpy(dst, src, dstlen);
}
return dstlen;
}
size_t RNG_GetNoise(void *buf, size_t maxbytes)
{
UnsignedWide microTickCount;
Microseconds(&microTickCount);
return CopyLowBits(buf, maxbytes, &microTickCount, sizeof(microTickCount));
}
void RNG_FileForRNG(const char *filename)
{
unsigned char buffer[BUFSIZ];
size_t bytes;
#ifdef notdef /*sigh*/
XP_File file;
unsigned long totalFileBytes = 0;
if (filename == NULL) /* For now, read in global history if filename is null */
file = XP_FileOpen(NULL, xpGlobalHistory,XP_FILE_READ_BIN);
else
file = XP_FileOpen(NULL, xpURL,XP_FILE_READ_BIN);
if (file != NULL) {
for (;;) {
bytes = XP_FileRead(buffer, sizeof(buffer), file);
if (bytes == 0) break;
RNG_RandomUpdate( buffer, bytes);
totalFileBytes += bytes;
if (totalFileBytes > 100*1024) break; /* No more than 100 K */
}
XP_FileClose(file);
}
#endif
/*
* Pass yet another snapshot of our highest resolution clock into
* the hash function.
*/
bytes = RNG_GetNoise(buffer, sizeof(buffer));
RNG_RandomUpdate(buffer, sizeof(buffer));
}
void RNG_SystemInfoForRNG()
{
/* Time */
{
unsigned long sec;
size_t bytes;
GetDateTime(&sec); /* Current time since 1970 */
RNG_RandomUpdate( &sec, sizeof(sec));
bytes = RNG_GetNoise(&sec, sizeof(sec));
RNG_RandomUpdate(&sec, bytes);
}
/* User specific variables */
{
MachineLocation loc;
ReadLocation(&loc);
RNG_RandomUpdate( &loc, sizeof(loc));
}
#if !TARGET_CARBON
/* User name */
{
unsigned long userRef;
Str32 userName;
GetDefaultUser(&userRef, userName);
RNG_RandomUpdate( &userRef, sizeof(userRef));
RNG_RandomUpdate( userName, sizeof(userName));
}
#endif
/* Mouse location */
{
Point mouseLoc;
GetMouse(&mouseLoc);
RNG_RandomUpdate( &mouseLoc, sizeof(mouseLoc));
}
/* Keyboard time threshold */
{
SInt16 keyTresh = LMGetKeyThresh();
RNG_RandomUpdate( &keyTresh, sizeof(keyTresh));
}
/* Last key pressed */
{
SInt8 keyLast;
keyLast = LMGetKbdLast();
RNG_RandomUpdate( &keyLast, sizeof(keyLast));
}
/* Volume */
{
UInt8 volume = LMGetSdVolume();
RNG_RandomUpdate( &volume, sizeof(volume));
}
#if !TARGET_CARBON
/* Current directory */
{
SInt32 dir = LMGetCurDirStore();
RNG_RandomUpdate( &dir, sizeof(dir));
}
#endif
/* Process information about all the processes in the machine */
{
ProcessSerialNumber process;
ProcessInfoRec pi;
process.highLongOfPSN = process.lowLongOfPSN = kNoProcess;
while (GetNextProcess(&process) == noErr)
{
FSSpec fileSpec;
pi.processInfoLength = sizeof(ProcessInfoRec);
pi.processName = NULL;
pi.processAppSpec = &fileSpec;
GetProcessInformation(&process, &pi);
RNG_RandomUpdate( &pi, sizeof(pi));
RNG_RandomUpdate( &fileSpec, sizeof(fileSpec));
}
}
#if !TARGET_CARBON
/* Heap */
{
THz zone = LMGetTheZone();
RNG_RandomUpdate( &zone, sizeof(zone));
}
#endif
/* Screen */
{
GDHandle h = GetMainDevice(); /* GDHandle is **GDevice */
RNG_RandomUpdate( *h, sizeof(GDevice));
}
#if !TARGET_CARBON
/* Scrap size */
{
SInt32 scrapSize = LMGetScrapSize();
RNG_RandomUpdate( &scrapSize, sizeof(scrapSize));
}
/* Scrap count */
{
SInt16 scrapCount = LMGetScrapCount();
RNG_RandomUpdate( &scrapCount, sizeof(scrapCount));
}
#else
{
ScrapRef scrap;
if (GetCurrentScrap(&scrap) == noErr) {
UInt32 flavorCount;
if (GetScrapFlavorCount(scrap, &flavorCount) == noErr) {
ScrapFlavorInfo* flavorInfo = (ScrapFlavorInfo*) malloc(flavorCount * sizeof(ScrapFlavorInfo));
if (flavorInfo != NULL) {
if (GetScrapFlavorInfoList(scrap, &flavorCount, flavorInfo) == noErr) {
UInt32 i;
RNG_RandomUpdate(&flavorCount, sizeof(flavorCount));
for (i = 0; i < flavorCount; ++i) {
Size flavorSize;
if (GetScrapFlavorSize(scrap, flavorInfo[i].flavorType, &flavorSize) == noErr)
RNG_RandomUpdate(&flavorSize, sizeof(flavorSize));
}
}
free(flavorInfo);
}
}
}
}
#endif
/* File stuff, last modified, etc. */
{
HParamBlockRec pb;
GetVolParmsInfoBuffer volInfo;
pb.ioParam.ioVRefNum = 0;
pb.ioParam.ioNamePtr = nil;
pb.ioParam.ioBuffer = (Ptr) &volInfo;
pb.ioParam.ioReqCount = sizeof(volInfo);
PBHGetVolParmsSync(&pb);
RNG_RandomUpdate( &volInfo, sizeof(volInfo));
}
#if !TARGET_CARBON
/* Event queue */
{
EvQElPtr eventQ;
for (eventQ = (EvQElPtr) LMGetEventQueue()->qHead;
eventQ;
eventQ = (EvQElPtr)eventQ->qLink)
RNG_RandomUpdate( &eventQ->evtQWhat, sizeof(EventRecord));
}
#endif
FE_ReadScreen();
RNG_FileForRNG(NULL);
}
void FE_ReadScreen()
{
UInt16 coords[4];
PixMapHandle pmap;
GDHandle gh;
UInt16 screenHeight;
UInt16 screenWidth; /* just what they say */
UInt32 bytesToRead; /* number of bytes we're giving */
UInt32 offset; /* offset into the graphics buffer */
UInt16 rowBytes;
UInt32 rowsToRead;
float bytesPerPixel; /* dependent on buffer depth */
Ptr p; /* temporary */
UInt16 x, y, w, h;
gh = LMGetMainDevice();
if ( !gh )
return;
pmap = (**gh).gdPMap;
if ( !pmap )
return;
RNG_GenerateGlobalRandomBytes( coords, sizeof( coords ) );
/* make x and y inside the screen rect */
screenHeight = (**pmap).bounds.bottom - (**pmap).bounds.top;
screenWidth = (**pmap).bounds.right - (**pmap).bounds.left;
x = coords[0] % screenWidth;
y = coords[1] % screenHeight;
w = ( coords[2] & 0x7F ) | 0x40; /* Make sure that w is in the range 64..128 */
h = ( coords[3] & 0x7F ) | 0x40; /* same for h */
bytesPerPixel = (**pmap).pixelSize / 8;
rowBytes = (**pmap).rowBytes & 0x7FFF;
/* starting address */
offset = ( rowBytes * y ) + (UInt32)( (float)x * bytesPerPixel );
/* don't read past the end of the pixmap's rowbytes */
bytesToRead = PR_MIN( (UInt32)( w * bytesPerPixel ),
(UInt32)( rowBytes - ( x * bytesPerPixel ) ) );
/* don't read past the end of the graphics device pixmap */
rowsToRead = PR_MIN( h,
( screenHeight - y ) );
p = GetPixBaseAddr( pmap ) + offset;
while ( rowsToRead-- )
{
RNG_RandomUpdate( p, bytesToRead );
p += rowBytes;
}
}
#endif

View File

@@ -1,146 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
# Sun Microsystems, Inc. All Rights Reserved.
#
# Contributor(s):
# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
CORE_DEPTH = ../../..
MODULE = nss
ifndef FREEBL_RECURSIVE_BUILD
LIBRARY_NAME = freebl
else
ifdef USE_PURE_32
CORE_DEPTH = ../../../..
LIBRARY_NAME = freebl_pure32
else
LIBRARY_NAME = freebl_hybrid
endif
endif
# same version as rest of freebl
LIBRARY_VERSION = _3
DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\"
REQUIRES =
EXPORTS = \
blapi.h \
blapit.h \
secrng.h \
shsign.h \
$(NULL)
PRIVATE_EXPORTS = \
secmpi.h \
ec.h \
$(NULL)
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c
ifdef MOZILLA_BSAFE_BUILD
CSRCS = \
fblstdlib.c \
sha_fast.c \
md2.c \
md5.c \
blapi_bsf.c \
$(MPI_SRCS) \
dh.c \
$(NULL)
else
CSRCS = \
ldvector.c \
prng_fips1861.c \
sysrand.c \
sha_fast.c \
md2.c \
md5.c \
sha512.c \
alg2268.c \
arcfour.c \
arcfive.c \
desblapi.c \
des.c \
rijndael.c \
aeskeywrap.c \
dh.c \
ec.c \
GFp_ecl.c \
GF2m_ecl.c \
pqg.c \
dsa.c \
rsa.c \
shvfy.c \
$(MPI_SRCS) \
$(NULL)
endif
ALL_CSRCS := $(CSRCS)
ALL_HDRS = \
blapi.h \
blapit.h \
des.h \
ec.h \
GFp_ecl.h \
GF2m_ecl.h \
loader.h \
rijndael.h \
secmpi.h \
sha.h \
sha_fast.h \
shsign.h \
vis_proto.h \
$(NULL)
ifdef AES_GEN_TBL
DEFINES += -DRIJNDAEL_GENERATE_TABLES
else
ifdef AES_GEN_TBL_M
DEFINES += -DRIJNDAEL_GENERATE_TABLES_MACRO
else
ifdef AES_GEN_VAL
DEFINES += -DRIJNDAEL_GENERATE_VALUES
else
ifdef AES_GEN_VAL_M
DEFINES += -DRIJNDAEL_GENERATE_VALUES_MACRO
else
DEFINES += -DRIJNDAEL_INCLUDE_TABLES
endif
endif
endif
endif

View File

@@ -1,39 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
libfreebl_3.so {
global:
FREEBL_GetVector;
local:
*;
};

View File

@@ -0,0 +1,197 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public
PROGRAM = viewer
CPPSRCS = \
$(TOOLKIT_CPPSRCS) \
nsBaseDialog.cpp \
nsFindDialog.cpp \
nsXPBaseWindow.cpp \
nsTableInspectorDialog.cpp \
nsImageInspectorDialog.cpp \
nsPrintSetupDialog.cpp \
nsBrowserWindow.cpp \
nsEditorMode.cpp \
nsSetupRegistry.cpp \
nsThrobber.cpp \
nsViewerApp.cpp \
nsWebCrawler.cpp \
$(NULL)
EXPORT_RESOURCE_SAMPLES := \
$(wildcard $(srcdir)/samples/test*.html) \
$(wildcard $(srcdir)/samples/toolbarTest*.xul) \
$(wildcard $(srcdir)/samples/treeTest*.xul) \
$(wildcard $(srcdir)/samples/treeTest*.css) \
$(wildcard $(srcdir)/samples/slider*.xul) \
$(wildcard $(srcdir)/samples/scrollbar*.xul) \
$(srcdir)/resources/find.html \
$(srcdir)/resources/printsetup.html \
$(srcdir)/resources/image_props.html \
$(srcdir)/samples/aform.css \
$(srcdir)/samples/bform.css \
$(srcdir)/samples/cform.css \
$(srcdir)/samples/demoform.css \
$(srcdir)/samples/mozform.css \
$(srcdir)/samples/xulTest.css \
$(srcdir)/samples/Anieyes.gif \
$(srcdir)/samples/gear1.gif \
$(srcdir)/samples/rock_gra.gif \
$(srcdir)/samples/beeptest.html \
$(srcdir)/samples/soundtest.html \
$(srcdir)/samples/bg.jpg \
$(srcdir)/samples/raptor.jpg \
$(srcdir)/samples/test.wav \
$(srcdir)/samples/checkboxTest.xul \
$(NULL)
EXPORT_RESOURCE_THROBBER := $(wildcard $(srcdir)/throbber/anim*.gif)
ifeq (,$(filter beos os2 rhapsody photon,$(MOZ_WIDGET_TOOLKIT)))
DIRS += unix
UNIX_VIEWER_TK_LIBS = $(DIST)/lib/libviewer_$(MOZ_WIDGET_TOOLKIT)_s.a
else
ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
BEOS_PROGRAM_RESOURCE = $(srcdir)/viewer-beos.rsrc
TOOLKIT_CPPSRCS = nsBeOSMain.cpp
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),photon)
TOOLKIT_CPPSRCS = nsPhMain.cpp nsPhMenu.cpp
endif
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk)
GTK_GLUE = -lgtksuperwin
endif
ifdef MOZ_OJI
JSJ_LIB = -ljsj
endif
XP_DIST_LIBS = \
-lraptorgfx \
-lmozjs \
-lxpcom \
$(JSJ_LIB) \
$(NULL)
XP_NS_UNDERBAR_CRAP = \
$(MOZ_NECKO_UTIL_LIBS) \
$(MOZ_TIMER_LIBS) \
$(MOZ_WIDGET_SUPPORT_LIBS) \
$(NULL)
XP_LIBS = \
$(XP_NS_UNDERBAR_CRAP) \
$(XP_DIST_LIBS) \
$(NSPR_LIBS) \
$(NULL)
ifdef MOZ_FULLCIRCLE
XP_LIBS += $(FULLCIRCLE_LIBS)
endif
LIBS = \
$(UNIX_VIEWER_TK_LIBS) \
$(GTK_GLUE) \
$(XP_LIBS) \
$(TK_LIBS) \
$(NULL)
MOTIF_LIBS = -lviewer_motif_s $(XP_LIBS) $(MOZ_MOTIF_LDFLAGS)
QT_LIBS = -lviewer_qt_s $(XP_LIBS) $(MOZ_QT_LDFLAGS)
XLIB_LIBS = -lviewer_xlib_s $(XP_LIBS) $(MOZ_XLIB_LDFLAGS)
GTK_LIBS = -lviewer_gtk_s -lgtksuperwin $(XP_LIBS) $(MOZ_GTK_LDFLAGS)
EXTRA_DEPS = \
$(addprefix $(DIST)/,$(patsubst -l%,bin/lib%.$(DLL_SUFFIX),$(XP_DIST_LIBS:-l%_s=lib/lib%_s.a))) \
$(UNIX_VIEWER_TK_LIBS) \
$(XP_NS_UNDERBAR_CRAP) \
$(NULL)
include $(topsrcdir)/config/rules.mk
CXXFLAGS += $(MOZ_TOOLKIT_REGISTRY_CFLAGS)
install:: $(PROGRAM) $(srcdir)/mozilla-viewer.sh
$(INSTALL) $(EXPORT_RESOURCE_SAMPLES) $(DIST)/bin/res/samples
$(INSTALL) $(EXPORT_RESOURCE_THROBBER) $(DIST)/bin/res/throbber
$(INSTALL) $(srcdir)/resources/viewer.properties $(DIST)/bin/res
$(INSTALL) $(srcdir)/mozilla-viewer.sh $(DIST)/bin
$(PROGRAM)_gtk: $(PROGOBJS) $(EXTRA_DEPS) Makefile Makefile.in $(DIST)/lib/libviewer_gtk_s.a
$(CCC) -o $@ $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(GTK_LIBS) $(OS_LIBS)
$(MOZ_POST_PROGRAM_COMMAND) $@
$(PROGRAM)_motif: $(PROGOBJS) $(EXTRA_DEPS) Makefile Makefile.in $(DIST)/lib/libviewer_motif_s.a
$(CCC) -o $@ $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(MOTIF_LIBS) $(OS_LIBS)
$(MOZ_POST_PROGRAM_COMMAND) $@
$(PROGRAM)_qt: $(PROGOBJS) $(EXTRA_DEPS) Makefile Makefile.in $(DIST)/lib/libviewer_qt_s.a
$(CCC) -o $@ $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(QT_LIBS) $(OS_LIBS)
$(MOZ_POST_PROGRAM_COMMAND) $@
$(PROGRAM)_xlib: $(PROGOBJS) $(EXTRA_DEPS) Makefile Makefile.in $(DIST)/lib/libviewer_xlib_s.a
$(CCC) -o $@ $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(XLIB_LIBS) $(OS_LIBS)
$(MOZ_POST_PROGRAM_COMMAND) $@
ifdef MOZ_ENABLE_GTK
install:: $(PROGRAM)_gtk
$(INSTALL) -m 555 $< $(DIST)/bin
clobber::
rm -f $(PROGRAM)_gtk
endif
ifdef MOZ_ENABLE_MOTIF
install:: $(PROGRAM)_motif
$(INSTALL) -m 555 $< $(DIST)/bin
clobber::
rm -f $(PROGRAM)_motif
endif
ifdef MOZ_ENABLE_QT
install:: $(PROGRAM)_qt
$(INSTALL) -m 555 $< $(DIST)/bin
clobber::
rm -f $(PROGRAM)_qt
endif
ifdef MOZ_ENABLE_XLIB
install:: $(PROGRAM)_xlib
$(INSTALL) -m 555 $< $(DIST)/bin
clobber::
rm -f $(PROGRAM)_xlib
endif

View File

@@ -0,0 +1,179 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "gdksuperwin.h"
#include "gtkmozbox.h"
#include "nsBrowserWindow.h"
#include "resources.h"
#include "nscore.h"
#include "stdio.h"
typedef GtkItemFactoryCallback GIFC;
void gtk_ifactory_cb (nsBrowserWindow *nbw,
guint callback_action,
GtkWidget *widget)
{
nbw->DispatchMenuItem(callback_action);
}
GtkItemFactoryEntry menu_items[] =
{
{ "/_File", nsnull, nsnull, 0, "<Branch>" },
{ "/File/_New Window", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_WINDOW_OPEN, nsnull },
{ "/File/_Open...", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_FILE_OPEN, nsnull },
{ "/File/_View Source", nsnull, (GIFC)gtk_ifactory_cb, VIEW_SOURCE, nsnull },
{ "/File/_Samples", nsnull, nsnull, 0, "<Branch>" },
{ "/File/Samples/demo #0", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO0, nsnull },
{ "/File/Samples/demo #1", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO1, nsnull },
{ "/File/Samples/demo #2", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO2, nsnull },
{ "/File/Samples/demo #3", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO3, nsnull },
{ "/File/Samples/demo #4", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO4, nsnull },
{ "/File/Samples/demo #5", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO5, nsnull },
{ "/File/Samples/demo #6", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO6, nsnull },
{ "/File/Samples/demo #7", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO7, nsnull },
{ "/File/Samples/demo #8", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO8, nsnull },
{ "/File/Samples/demo #9", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO9, nsnull },
{ "/File/Samples/demo #10", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO10, nsnull },
{ "/File/Samples/demo #11", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO11, nsnull },
{ "/File/Samples/demo #12", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO12, nsnull },
{ "/File/Samples/demo #13", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO13, nsnull },
{ "/File/Samples/demo #14", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO14, nsnull },
{ "/File/Samples/demo #15", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO15, nsnull },
{ "/File/Samples/demo #16", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO16, nsnull },
{ "/File/Samples/demo #17", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEMO17, nsnull },
{ "/File/_Test Sites", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOP100, nsnull },
{ "/File/XPToolkit Tests", nsnull, nsnull, 0, "<Branch>" },
{ "/File/XPToolkit Tests/Toolbar Test 1", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_XPTOOLKITTOOLBAR1, nsnull },
{ "/File/XPToolkit Tests/Tree Test 1", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_XPTOOLKITTREE1, nsnull },
{ "/File/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/File/Print Preview", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_ONE_COLUMN, nsnull },
{ "/File/Print", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_PRINT, nsnull },
{ "/File/Print Setup", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_PRINT_SETUP, nsnull },
{ "/File/sep2", nsnull, nsnull, 0, "<Separator>" },
{ "/File/_Exit", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_EXIT, nsnull },
{ "/_Edit", nsnull, nsnull, 0, "<Branch>" },
{ "/Edit/Cu_t", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_EDIT_CUT, nsnull },
{ "/Edit/_Copy", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_EDIT_COPY, nsnull },
{ "/Edit/_Paste", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_EDIT_PASTE, nsnull },
{ "/Edit/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Edit/Select All", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_EDIT_SELECTALL, nsnull },
{ "/Edit/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Edit/Find in Page", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_EDIT_FINDINPAGE, nsnull },
//#ifdef DEBUG // turning off for now
{ "/_Debug", nsnull, nsnull, 0, "<Branch>" },
{ "/Debug/_Visual Debugging", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_VISUAL_DEBUGGING,nsnull },
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Event Debugging/Toggle Paint Flashing", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOGGLE_PAINT_FLASHING,nsnull },
{ "/Debug/Event Debugging/Toggle Paint Dumping", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOGGLE_PAINT_DUMPING,nsnull },
{ "/Debug/Event Debugging/Toggle Invalidate Dumping", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOGGLE_INVALIDATE_DUMPING,nsnull },
{ "/Debug/Event Debugging/Toggle Event Dumping", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOGGLE_EVENT_DUMPING,nsnull },
{ "/Debug/Event Debugging/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Event Debugging/Toggle Motion Event Dumping", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOGGLE_MOTION_EVENT_DUMPING,nsnull },
{ "/Debug/Event Debugging/Toggle Crossing Event Dumping", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOGGLE_CROSSING_EVENT_DUMPING,nsnull },
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/_Reflow Test", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_REFLOW_TEST, nsnull },
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Dump _Content", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DUMP_CONTENT, nsnull },
{ "/Debug/Dump _Frames", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DUMP_FRAMES, nsnull },
{ "/Debug/Dump _Views", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DUMP_VIEWS, nsnull },
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Dump _Style Sheets", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DUMP_STYLE_SHEETS, nsnull },
{ "/Debug/Dump _Style Contexts", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DUMP_STYLE_CONTEXTS, nsnull},
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Show Content Size", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SHOW_CONTENT_SIZE,nsnull },
{ "/Debug/Show Frame Size", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SHOW_FRAME_SIZE, nsnull },
{ "/Debug/Show Style Size", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SHOW_STYLE_SIZE, nsnull },
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Debug Save", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEBUGSAVE, nsnull },
{ "/Debug/Debug Output Text", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DISPLAYTEXT, nsnull },
{ "/Debug/Debug Output HTML", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DISPLAYHTML, nsnull },
{ "/Debug/Debug Toggle Selection", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_TOGGLE_SELECTION,nsnull },
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Debug Robot", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_DEBUGROBOT, nsnull },
{ "/Debug/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Debug/Show Content Quality", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SHOW_CONTENT_QUALITY, nsnull },
{ "/_Style", nsnull, nsnull, 0, "<Branch>" },
{ "/Style/Select _Style Sheet", nsnull, nsnull, 0, "<Branch>" },
{ "/Style/Select Style Sheet/List Available Sheets", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SELECT_STYLE_LIST, nsnull },
{ "/Style/Select Style Sheet/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Style/Select Style Sheet/Select Default", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SELECT_STYLE_DEFAULT, nsnull },
{ "/Style/Select Style Sheet/sep1", nsnull, nsnull, 0, "<Separator>" },
{ "/Style/Select Style Sheet/Select Alternative 1", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SELECT_STYLE_ONE, nsnull },
{ "/Style/Select Style Sheet/Select Alternative 2", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SELECT_STYLE_TWO, nsnull },
{ "/Style/Select Style Sheet/Select Alternative 3", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SELECT_STYLE_THREE, nsnull },
{ "/Style/Select Style Sheet/Select Alternative 4", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_SELECT_STYLE_FOUR, nsnull },
{ "/Style/_Compatibility Mode", nsnull, nsnull, 0, "<Branch>" },
{ "/Style/Compatibility Mode/Nav Quirks", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_NAV_QUIRKS_MODE, nsnull },
{ "/Style/Compatibility Mode/Standard", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_STANDARD_MODE, nsnull },
{ "/Style/_Widget Render Mode", nsnull, nsnull, 0, "<Branch>" },
{ "/Style/Widget Render Mode/Native", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_NATIVE_WIDGET_MODE, nsnull },
{ "/Style/Widget Render Mode/Gfx", nsnull, (GIFC)gtk_ifactory_cb, VIEWER_GFX_WIDGET_MODE, nsnull },
//#endif
{ "/_Tools", nsnull, nsnull, 0, "<Branch>" },
{ "/Tools/_JavaScript Console", nsnull, (GIFC)gtk_ifactory_cb, JS_CONSOLE, nsnull },
{ "/Tools/_Editor Mode", nsnull, (GIFC)gtk_ifactory_cb, EDITOR_MODE, nsnull }
};
void CreateViewerMenus(nsIWidget * aParent,
gpointer data,
GtkWidget ** aMenuBarOut)
{
NS_ASSERTION(nsnull != aParent,"null parent.");
NS_ASSERTION(nsnull != aMenuBarOut,"null out param.");
GtkItemFactory *item_factory;
GtkWidget *menubar;
GdkSuperWin *gdkSuperWin;
GtkWidget *mozBox;
gdkSuperWin = (GdkSuperWin*)aParent->GetNativeData(NS_NATIVE_WIDGET);
int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", nsnull);
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, data);
menubar = gtk_item_factory_get_widget (item_factory, "<main>");
gtk_menu_bar_set_shadow_type (GTK_MENU_BAR(menubar), GTK_SHADOW_NONE);
NS_ASSERTION(GDK_IS_SUPERWIN(gdkSuperWin), "code assumes a gdksuperwin.");
mozBox = gtk_mozbox_new(gdkSuperWin->bin_window);
NS_ASSERTION((mozBox != NULL), "failed to create mozBox.");
gtk_container_add(GTK_CONTAINER(mozBox), menubar);
gtk_mozbox_set_position(GTK_MOZBOX(mozBox), 0, 0 );
gtk_widget_show(mozBox);
gtk_widget_show(menubar);
*aMenuBarOut = menubar;
}

View File

@@ -0,0 +1,67 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = xpwidgets support
#
# Dont build the DSO under the 'build' directory as windows does.
#
# The DSOs get built in the toolkit dir itself. Do this so that
# multiple implementations of widget can be built on the same
# source tree.
#
ifndef MOZ_MONOLITHIC_TOOLKIT
ifdef MOZ_ENABLE_GTK
DIRS += gtksuperwin
DIRS += gtk
endif
ifdef MOZ_ENABLE_MOTIF
DIRS += motif
endif
ifdef MOZ_ENABLE_XLIB
DIRS += xlib
endif
ifdef MOZ_ENABLE_QT
DIRS += qt
endif
else
DIRS += $(MOZ_WIDGET_TOOLKIT)
endif
# unix_services are only useful in unix, duh...
ifeq (,$(filter beos os2 rhapsody photon,$(MOZ_WIDGET_TOOLKIT)))
DIRS += unix_services
endif
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,100 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = widget_gtk
REQUIRES = util img xpcom raptor netlib
CPPSRCS = \
nsAppShell.cpp \
nsButton.cpp \
nsCheckButton.cpp \
nsClipboard.cpp \
nsComboBox.cpp \
nsContextMenu.cpp \
nsDragService.cpp \
nsFilePicker.cpp \
nsFileWidget.cpp \
nsFontRetrieverService.cpp \
nsFontSizeIterator.cpp \
nsGtkEventHandler.cpp \
nsGtkUtils.cpp \
nsLabel.cpp \
nsListBox.cpp \
nsLookAndFeel.cpp \
nsMenu.cpp \
nsMenuBar.cpp \
nsMenuItem.cpp \
nsPopUpMenu.cpp \
nsRadioButton.cpp \
nsScrollbar.cpp \
nsSound.cpp \
nsTextAreaWidget.cpp \
nsTextHelper.cpp \
nsTextWidget.cpp \
nsToolkit.cpp \
nsWidget.cpp \
nsWidgetFactory.cpp \
nsWindow.cpp \
$(NULL)
SHARED_LIBRARY_LIBS = $(DIST)/lib/libraptorbasewidget_s.a
EXTRA_DSO_LDOPTS = \
$(MKSHLIB_FORCE_ALL) \
$(SHARED_LIBRARY_LIBS) \
$(MKSHLIB_UNFORCE_ALL) \
$(MOZ_COMPONENT_LIBS) \
-lraptorgfx \
$(NULL)
ifndef MOZ_MONOLITHIC_TOOLKIT
EXTRA_DSO_LDOPTS += -L$(DIST)/lib -lgtksuperwin $(MOZ_GTK_LDFLAGS)
else
EXTRA_DSO_LDOPTS += $(TK_LIBS)
endif
include $(topsrcdir)/config/rules.mk
ifndef MOZ_MONOLITHIC_TOOLKIT
CXXFLAGS += $(MOZ_GTK_CFLAGS)
CFLAGS += $(MOZ_GTK_CFLAGS)
else
CXXFLAGS += $(TK_CFLAGS)
CFLAGS += $(TK_CFLAGS)
endif
DEFINES += -D_IMPL_NS_WIDGET -DUSE_XIM
ifeq ($(OS_ARCH), Linux)
DEFINES += -D_BSD_SOURCE
endif
INCLUDES += \
-I$(srcdir)/../xpwidgets \
-I$(srcdir) \
$(NULL)
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile

View File

@@ -0,0 +1,292 @@
/* XPM */
static char * mozilla_icon_xpm[] = {
"32 32 257 2",
" c None",
". c #AA7303",
"+ c #A67003",
"@ c #B77C03",
"# c #8D6003",
"$ c #8D6004",
"% c #6C4A04",
"& c #3A2804",
"* c #6B4802",
"= c #9B6903",
"- c #5A2C04",
"; c #411B04",
"> c #9D6A03",
", c #7A5203",
"' c #510D04",
") c #6B1104",
"! c #7D5503",
"~ c #674604",
"{ c #C21E04",
"] c #C21D04",
"^ c #523804",
"/ c #513702",
"( c #552904",
"_ c #DD2204",
": c #DF2204",
"< c #582904",
"[ c #5F3F02",
"} c #6B2504",
"| c #FE2604",
"1 c #AB7303",
"2 c #9B6904",
"3 c #C31F04",
"4 c #FE2704",
"5 c #A81904",
"6 c #926304",
"7 c #4D3302",
"8 c #483104",
"9 c #C61E04",
"0 c #B11B04",
"a c #891604",
"b c #761204",
"c c #614304",
"d c #775102",
"e c #795102",
"f c #785102",
"g c #C58603",
"h c #642404",
"i c #B21A04",
"j c #1F0604",
"k c #550E04",
"l c #631004",
"m c #402404",
"n c #AF7703",
"o c #3D2902",
"p c #7F5602",
"q c #805604",
"r c #0C0904",
"s c #080604",
"t c #080706",
"u c #090604",
"v c #060404",
"w c #620F04",
"x c #7A1304",
"y c #030204",
"z c #570E04",
"A c #721204",
"B c #270704",
"C c #080504",
"D c #0A0604",
"E c #533804",
"F c #A56F02",
"G c #B87C03",
"H c #3B2804",
"I c #A51904",
"J c #FC2704",
"K c #D62004",
"L c #691004",
"M c #C01E04",
"N c #6D1004",
"O c #9C1804",
"P c #B31C04",
"Q c #150404",
"R c #801404",
"S c #DD2304",
"T c #120404",
"U c #130404",
"V c #500C04",
"W c #CC1E04",
"X c #AA1A04",
"Y c #100904",
"Z c #B47A03",
"` c #A77103",
" . c #513704",
".. c #891704",
"+. c #F62604",
"@. c #BA1D04",
"#. c #3C0A04",
"$. c #EB2304",
"%. c #DE2304",
"&. c #560E04",
"*. c #E82304",
"=. c #FE2804",
"-. c #BE1D04",
";. c #F12404",
">. c #661004",
",. c #020204",
"'. c #5E0F04",
"). c #A61A04",
"!. c #4A3204",
"~. c #BC7E03",
"{. c #8E6002",
"]. c #684604",
"^. c #390D04",
"/. c #EE2404",
"(. c #FE2904",
"_. c #7D1304",
":. c #8C1504",
"<. c #200604",
"[. c #A81A04",
"}. c #E72204",
"|. c #DA2004",
"1. c #070204",
"2. c #280704",
"3. c #543904",
"4. c #9F6C02",
"5. c #674602",
"6. c #B47B04",
"7. c #311004",
"8. c #B11C04",
"9. c #AA1B04",
"0. c #6A1104",
"a. c #801504",
"b. c #2B0704",
"c. c #09090A",
"d. c #450B04",
"e. c #360904",
"f. c #DC2204",
"g. c #EE2504",
"h. c #C11D04",
"i. c #6F1104",
"j. c #704B04",
"k. c #9C6902",
"l. c #A56F03",
"m. c #5F4004",
"n. c #8D1604",
"o. c #440A04",
"p. c #1A0504",
"q. c #931604",
"r. c #621004",
"s. c #7F1404",
"t. c #921704",
"u. c #F82504",
"v. c #F52504",
"w. c #981804",
"x. c #241804",
"y. c #5B3E04",
"z. c #D82204",
"A. c #D02004",
"B. c #DA2104",
"C. c #D52104",
"D. c #2A1A04",
"E. c #AC7403",
"F. c #2B1C04",
"G. c #D04004",
"H. c #FC3C04",
"I. c #F94E04",
"J. c #881504",
"K. c #FC2604",
"L. c #792804",
"M. c #AC7503",
"N. c #9A6803",
"O. c #782804",
"P. c #F66504",
"Q. c #F94B04",
"R. c #F46804",
"S. c #F46604",
"T. c #F76504",
"U. c #FB4204",
"V. c #C13D04",
"W. c #5D0E04",
"X. c #DA2204",
"Y. c #741604",
"Z. c #8C5E03",
"`. c #885B03",
" + c #8B1904",
".+ c #DE2204",
"++ c #D22D04",
"@+ c #C42D04",
"#+ c #580E04",
"$+ c #9F1804",
"%+ c #895D04",
"&+ c #D62204",
"*+ c #371904",
"=+ c #2C1A04",
"-+ c #4A0C04",
";+ c #140404",
">+ c #AB1A04",
",+ c #DA2304",
"'+ c #6A4702",
")+ c #754F02",
"!+ c #821404",
"~+ c #462B04",
"{+ c #B37A03",
"]+ c #B17803",
"^+ c #714C04",
"/+ c #580F04",
"(+ c #E32204",
"_+ c #DD2104",
":+ c #611D04",
"<+ c #BA7F03",
"[+ c #B27803",
"}+ c #6F1D04",
"|+ c #FD2704",
"1+ c #F22504",
"2+ c #634304",
"3+ c #875B03",
"4+ c #734F02",
"5+ c #805704",
"6+ c #1D0504",
"7+ c #DB2204",
"8+ c #EA2404",
"9+ c #2E0804",
"0+ c #815803",
"a+ c #941704",
"b+ c #C11E04",
"c+ c #391B04",
"d+ c #A77104",
"e+ c #B67C04",
"f+ c #371D04",
"g+ c #360A04",
"h+ c #573A04",
"i+ c #372604",
"j+ c #3E2104",
"k+ c #B57A03",
"l+ c #B57B03",
"m+ c #603F04",
"n+ c #430A04",
"o+ c #351904",
"p+ c #A36E03",
"q+ c #BE8103",
"r+ c #1D1404",
"s+ c #483004",
"t+ c #A26E03",
"u+ c #6D4B02",
"v+ c #825804",
"w+ c #0B0804",
"x+ c #976603",
"y+ c #815703",
"z+ c #926404",
"A+ c #895D03",
"B+ c #614202",
"C+ c #9A6804",
"D+ c #C88704",
"E+ c #C18303",
"F+ c #654302",
"G+ c #744F02",
"H+ c #704B02",
" ",
" . ",
" + @ ",
" # $ ",
" % & * ",
" = - ; > ",
" , ' ) ! ",
" ~ { ] ^ ",
" / ( _ : < [ ",
" . } | | } 1 ",
" 2 3 | 4 5 6 ",
" 7 8 9 0 a b c ",
" d e f f f d d d d d d g h i j k l m n d d d d d d d d d d d o ",
" p q r s s s s t s s u v w x y z A B C D D D D D s s s s E F ",
" G H I J 4 | 4 | K L L M N O P Q R | S T U V W X Y Z ",
" ` ...+.| 4 @.#.$.4 | %.&.*.4 =.-.;.>.,.'.).!.~. ",
" {.].^./.(.X _.;.| :.T <.[.| }.z | |.1.2.3.4. ",
" 5.6.7.8.9.0.a.b.c.d.e.f.g.h.&.| i.u j.k. ",
" l.m.n.o.p.q._.r.a.s.t.u.v.w.x.Z ",
" {.y.P z.R A.v.x j B.| C.D.E. ",
" F.G.H.I.4 | 4 t.J.f.K.L.M. ",
" N.O.P.Q.R.S.T.U.V.W.X.4 Y.Z. ",
" `. +4 =.| | .+++@+#+$+| K %+ ",
" %+&+| | | I *+=+-+;+>+,+&+x.'+ ",
" )+=+X.=.| !+~+{+]+^+,./+(+_+:+<+ ",
" [+}+|+1+) 2+3+ 4+5+6+7+8+9+0+ ",
" $ a+b+c+d+ e+f+0.g+h+ ",
" i+A j+k+ l+m+n+o+p+ ",
" q+r+s+t+ u+v+w+x+ ",
" y+z+A+ B+C+2 ",
" D+ E+F+ ",
" G+ H+ "};

View File

@@ -0,0 +1,63 @@
/* XPM */
static char * mozicon50_xpm[] = {
"50 51 9 1",
" c None",
". c #000000",
"+ c #FF0000",
"@ c #808000",
"# c #800000",
"$ c #FF6633",
"% c #990066",
"& c #FF00FF",
"* c #222222",
" ",
" @ ",
" $@ ",
" @@ ",
" @@$ ",
" $@*@ ",
" @@.@ ",
" @..@ ",
" $@..@@ ",
" $@##*@ ",
" @*#+.@ ",
" @.++.@$ ",
" $@.++.@$ ",
" @*#++#*@ ",
" @.++++.@ ",
" $@.++++.@$ ",
" @*#++++**@ ",
" @.#++++#.@ ",
" $@.++####.@ ",
" @@*+#*##*.@@ ",
"*@@@@@@@@@@@@@@@@@@@.#+..*##*#@@@@@@@@@@@@@@@@@@@*",
" *@@*................+#..*###.................@@* ",
" %@@@.#++++++++++++#**#*#++.###++*...#+++#.*@@* ",
" *@@.#+++++++++#.##++#+#+*.#+++#..##++#.@@@% ",
" $@..+++++++.#++++++##++++#++#...++*.@@$ ",
" @@*.#+++++.#+++++*.#++++##++#.*...@@ ",
" $@@.#+++#*++++#....#+++*#+++...*@$ ",
" *@@..++#*++#**.*.*+++#.#++*..@@$ ",
" $@*.++******#+++++#+#+++..@@ ",
" $@@.##..*$#**#+#*#++++..@@ ",
" $@@.#+#***##...#++++.*@@ ",
" %@@*++++++++#.#++++.@@ ",
" @.#+++++++++.##+++.@$ ",
" @.+$$$$$+$$$#*#+++*@@ ",
" $@*+$$$$$$$+$#.#+++#.@ ",
" @*#+++++++++++.#++++.@ ",
" @.#+++++++#*++.##+++.@$ ",
" $@.+++++++....#..+#++*@@ ",
" @@*+++++#.*@@@...*+++#.@ ",
" @.#++++#.@@@ @@..#++++.@ ",
" @.++++*.@@$ %@@..+++#.@@ ",
" $@.+++..@@* $@*.#+#**@ ",
" @@#+#.*@$% $@@.##..@ ",
" @.##.@@ @@..#.@$ ",
" $@.*.@@$ @@**.@$ ",
" $@.*@@ %$@@.*@ ",
" @.@@$ *@@.@ ",
" @@@$ %@@@$ ",
" $@@% %@@@ ",
" @@ $@ ",
" $ * "};

View File

@@ -0,0 +1,459 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "prmon.h"
#include "nsCOMPtr.h"
#include "nsAppShell.h"
#include "nsIAppShell.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsICmdLineService.h"
#include "nsGtkEventHandler.h"
#include <stdlib.h>
#ifdef MOZ_GLE
#include <gle/gle.h>
#endif
#include "nsIWidget.h"
#include "nsIPref.h"
#include "glib.h"
struct OurGdkIOClosure {
GdkInputFunction function;
gpointer data;
};
static gboolean
our_gdk_io_invoke(GIOChannel* source, GIOCondition condition, gpointer data)
{
OurGdkIOClosure* ioc = (OurGdkIOClosure*) data;
if (ioc) {
(*ioc->function)(ioc->data, g_io_channel_unix_get_fd(source),
GDK_INPUT_READ);
}
return TRUE;
}
static void
our_gdk_io_destroy(gpointer data)
{
OurGdkIOClosure* ioc = (OurGdkIOClosure*) data;
if (ioc) {
g_free(ioc);
}
}
static gint
our_gdk_input_add (gint source,
GdkInputFunction function,
gpointer data,
gint priority)
{
guint result;
OurGdkIOClosure *closure = g_new (OurGdkIOClosure, 1);
GIOChannel *channel;
closure->function = function;
closure->data = data;
channel = g_io_channel_unix_new (source);
result = g_io_add_watch_full (channel, priority, G_IO_IN,
our_gdk_io_invoke,
closure, our_gdk_io_destroy);
g_io_channel_unref (channel);
return result;
}
//-------------------------------------------------------------------------
//
// XPCOM CIDs
//
//-------------------------------------------------------------------------
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
// a linked, ordered list of event queues and their tokens
class EventQueueToken {
public:
EventQueueToken(nsIEventQueue *aQueue, const gint aToken);
virtual ~EventQueueToken();
nsIEventQueue *mQueue;
gint mToken;
EventQueueToken *mNext;
};
EventQueueToken::EventQueueToken(nsIEventQueue *aQueue, const gint aToken) {
mQueue = aQueue;
NS_IF_ADDREF(mQueue);
mToken = aToken;
mNext = 0;
}
EventQueueToken::~EventQueueToken(){
NS_IF_RELEASE(mQueue);
}
class EventQueueTokenQueue {
public:
EventQueueTokenQueue();
virtual ~EventQueueTokenQueue();
nsresult PushToken(nsIEventQueue *aQueue, gint aToken);
PRBool PopToken(nsIEventQueue *aQueue, gint *aToken);
private:
EventQueueToken *mHead;
};
EventQueueTokenQueue::EventQueueTokenQueue() {
mHead = 0;
}
EventQueueTokenQueue::~EventQueueTokenQueue() {
// if we reach this point with an empty token queue, well, fab. however,
// we expect the first event queue to still be active. so we take
// special care to unhook that queue (not that failing to do so seems
// to hurt anything). more queues than that would be an error.
//NS_ASSERTION(!mHead || !mHead->mNext, "event queue token list deleted when not empty");
// (and skip the assertion for now. we're leaking event queues because they
// are referenced by things that leak, so this assertion goes off a lot.)
if (mHead) {
gdk_input_remove(mHead->mToken);
delete mHead;
// and leak the rest. it's an error, anyway
}
}
nsresult EventQueueTokenQueue::PushToken(nsIEventQueue *aQueue, gint aToken) {
EventQueueToken *newToken = new EventQueueToken(aQueue, aToken);
NS_ASSERTION(newToken, "couldn't allocate token queue element");
if (!newToken)
return NS_ERROR_OUT_OF_MEMORY;
newToken->mNext = mHead;
mHead = newToken;
return NS_OK;
}
PRBool EventQueueTokenQueue::PopToken(nsIEventQueue *aQueue, gint *aToken) {
EventQueueToken *token, *lastToken;
PRBool found = PR_FALSE;
NS_ASSERTION(mHead, "attempt to retrieve event queue token from empty queue");
if (mHead)
NS_ASSERTION(mHead->mQueue == aQueue, "retrieving event queue from past head of queue queue");
token = mHead;
lastToken = 0;
while (token && token->mQueue != aQueue) {
lastToken = token;
token = token->mNext;
}
if (token) {
if (lastToken)
lastToken->mNext = token->mNext;
else
mHead = token->mNext;
found = PR_TRUE;
*aToken = token->mToken;
delete token;
}
return found;
}
//-------------------------------------------------------------------------
//
// nsAppShell constructor
//
//-------------------------------------------------------------------------
nsAppShell::nsAppShell()
{
NS_INIT_REFCNT();
mDispatchListener = 0;
mEventQueueTokens = new EventQueueTokenQueue();
// throw on error would really be civilized here
NS_ASSERTION(mEventQueueTokens, "couldn't allocate event queue token queue");
}
//-------------------------------------------------------------------------
//
// nsAppShell destructor
//
//-------------------------------------------------------------------------
nsAppShell::~nsAppShell()
{
delete mEventQueueTokens;
}
//-------------------------------------------------------------------------
//
// nsISupports implementation macro
//
//-------------------------------------------------------------------------
NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell)
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener)
{
mDispatchListener = aDispatchListener;
return NS_OK;
}
static void event_processor_callback(gpointer data,
gint source,
GdkInputCondition condition)
{
nsIEventQueue *eventQueue = (nsIEventQueue*)data;
if (eventQueue)
eventQueue->ProcessPendingEvents();
}
#define PREF_NCOLS "browser.ncols"
#define PREF_INSTALLCMAP "browser.installcmap"
static void
HandleColormapPrefs( void )
{
PRInt32 ivalue = 0;
PRBool bvalue;
nsresult rv;
/* The default is to do nothing. INSTALLCMAP has precedence over
NCOLS. Ignore the fact we can't do this if it fails, as it is
not critical */
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (NS_FAILED(rv) || (!prefs))
return;
/* first check ncols */
rv = prefs->GetIntPref(PREF_NCOLS, &ivalue);
if (NS_SUCCEEDED(rv) && ivalue >= 0 && ivalue <= 255 ) {
gdk_rgb_set_min_colors( ivalue );
return;
}
/* next check installcmap */
rv = prefs->GetBoolPref(PREF_INSTALLCMAP, &bvalue);
if (NS_SUCCEEDED(rv)) {
if ( PR_TRUE == bvalue )
gdk_rgb_set_min_colors( 255 ); // force it
else
gdk_rgb_set_min_colors( 0 );
}
}
//-------------------------------------------------------------------------
//
// Create the application shell
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Create(int *bac, char **bav)
{
gchar *home=nsnull;
gchar *path=nsnull;
int argc = bac ? *bac : 0;
char **argv = bav;
#if 1
nsresult rv;
NS_WITH_SERVICE(nsICmdLineService, cmdLineArgs, kCmdLineServiceCID, &rv);
if (NS_SUCCEEDED(rv))
{
rv = cmdLineArgs->GetArgc(&argc);
if(NS_FAILED(rv))
argc = bac ? *bac : 0;
rv = cmdLineArgs->GetArgv(&argv);
if(NS_FAILED(rv))
argv = bav;
}
#endif
gtk_set_locale ();
gtk_init (&argc, &argv);
// It is most convenient for us to intercept our events after
// they have been converted to GDK, but before GTK+ gets them
gdk_event_handler_set (handle_gdk_event, NULL, NULL);
#ifdef MOZ_GLE
gle_init (&argc, &argv);
#endif
// delete the cmdLineArgs thing?
HandleColormapPrefs();
gdk_rgb_init();
home = g_get_home_dir();
if ((char*)nsnull != home) {
path = g_strdup_printf("%s%c%s", home, G_DIR_SEPARATOR, ".gtkrc");
if ((char *)nsnull != path) {
gtk_rc_parse(path);
g_free(path);
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Spinup - do any preparation necessary for running a message loop
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Spinup()
{
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Spindown - do any cleanup necessary for finishing a message loop
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Spindown()
{
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Run
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Run()
{
NS_ADDREF_THIS();
nsresult rv = NS_OK;
nsIEventQueue * EQueue = nsnull;
// Get the event queue service
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
if (NS_FAILED(rv)) {
NS_ASSERTION("Could not obtain event queue service", PR_FALSE);
return rv;
}
#ifdef DEBUG
printf("Got the event queue from the service\n");
#endif /* DEBUG */
//Get the event queue for the thread.
rv = eventQService->GetThreadEventQueue(PR_GetCurrentThread(), &EQueue);
// If a queue already present use it.
if (EQueue)
goto done;
// Create the event queue for the thread
rv = eventQService->CreateThreadEventQueue();
if (NS_OK != rv) {
NS_ASSERTION("Could not create the thread event queue", PR_FALSE);
return rv;
}
//Get the event queue for the thread
rv = eventQService->GetThreadEventQueue(PR_GetCurrentThread(), &EQueue);
if (NS_OK != rv) {
NS_ASSERTION("Could not obtain the thread event queue", PR_FALSE);
return rv;
}
done:
#ifdef DEBUG
printf("Calling gdk_input_add with event queue\n");
#endif /* DEBUG */
// (has to be called explicitly for this, the primordial appshell, because
// of startup ordering problems.)
ListenToEventQueue(EQueue, PR_TRUE);
gtk_main();
NS_IF_RELEASE(EQueue);
Release();
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Exit a message handler loop
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsAppShell::Exit()
{
gtk_main_quit ();
return NS_OK;
}
// does nothing. used by xp code with non-gtk expectations.
// this method will be removed once xp eventloops are working.
NS_IMETHODIMP nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *& aEvent)
{
aRealEvent = PR_FALSE;
aEvent = 0;
return NS_OK;
}
// simply executes one iteration of the event loop. used by xp code with
// non-gtk expectations.
// this method will be removed once xp eventloops are working.
NS_IMETHODIMP nsAppShell::DispatchNativeEvent(PRBool aRealEvent, void *aEvent)
{
g_main_iteration(PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue *aQueue,
PRBool aListen)
{
// tell gdk to listen to the event queue or not
gint queueToken;
if (aListen) {
queueToken = our_gdk_input_add(aQueue->GetEventQueueSelectFD(),
event_processor_callback,
aQueue, G_PRIORITY_DEFAULT_IDLE);
mEventQueueTokens->PushToken(aQueue, queueToken);
} else {
if (mEventQueueTokens->PopToken(aQueue, &queueToken))
gdk_input_remove(queueToken);
}
return NS_OK;
}

View File

@@ -0,0 +1,50 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsAppShell_h__
#define nsAppShell_h__
#include "nsIAppShell.h"
#include <gtk/gtk.h>
/**
* Native GTK+ Application shell wrapper
*/
class EventQueueTokenQueue;
class nsAppShell : public nsIAppShell
{
public:
nsAppShell();
virtual ~nsAppShell();
NS_DECL_ISUPPORTS
NS_DECL_NSIAPPSHELL
private:
nsDispatchListener *mDispatchListener;
EventQueueTokenQueue *mEventQueueTokens;
};
#endif // nsAppShell_h__

View File

@@ -0,0 +1,156 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsGtkEventHandler.h"
#include "nsButton.h"
#include "nsString.h"
NS_IMPL_ADDREF_INHERITED(nsButton, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsButton, nsWidget)
NS_IMPL_QUERY_INTERFACE2(nsButton, nsIButton, nsIWidget)
//-------------------------------------------------------------------------
//
// nsButton constructor
//
//-------------------------------------------------------------------------
nsButton::nsButton() : nsWidget() , nsIButton()
{
}
//-------------------------------------------------------------------------
//
// Create the native Button widget
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsButton::CreateNative(GtkObject *parentWindow)
{
#ifdef USE_SUPERWIN
if (!GDK_IS_SUPERWIN(parentWindow)) {
g_print("Damn, brother. That's not a superwin.\n");
return NS_ERROR_FAILURE;
}
GdkSuperWin *superwin = GDK_SUPERWIN(parentWindow);
mMozBox = gtk_mozbox_new(superwin->bin_window);
#endif
mWidget = gtk_button_new_with_label("");
gtk_widget_set_name(mWidget, "nsButton");
#ifdef USE_SUPERWIN
// make sure that we put the scrollbar into the mozbox
gtk_container_add(GTK_CONTAINER(mMozBox), mWidget);
#endif /* USE_SUPERWIN */
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsButton destructor
//
//-------------------------------------------------------------------------
nsButton::~nsButton()
{
}
void nsButton::InitCallbacks(char * aName)
{
InstallButtonPressSignal(mWidget);
InstallButtonReleaseSignal(mWidget);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_EXPOSURE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
}
//-------------------------------------------------------------------------
//
// Set this button label
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsButton::SetLabel(const nsString& aText)
{
NS_ALLOC_STR_BUF(label, aText, 256);
gtk_label_set(GTK_LABEL(GTK_BIN (mWidget)->child), label);
NS_FREE_STR_BUF(label);
return (NS_OK);
}
//-------------------------------------------------------------------------
//
// Get this button label
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsButton::GetLabel(nsString& aBuffer)
{
char * text;
gtk_label_get(GTK_LABEL(GTK_BIN (mWidget)->child), &text);
aBuffer.SetLength(0);
aBuffer.Append(text);
return (NS_OK);
}
//-------------------------------------------------------------------------
//
// set font for button
//
//-------------------------------------------------------------------------
/* virtual */
void nsButton::SetFontNative(GdkFont *aFont)
{
GtkStyle *style = gtk_style_copy(GTK_BIN (mWidget)->child->style);
// gtk_style_copy ups the ref count of the font
gdk_font_unref (style->font);
style->font = aFont;
gdk_font_ref(style->font);
gtk_widget_set_style(GTK_BIN (mWidget)->child, style);
gtk_style_unref(style);
}

View File

@@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsButton_h__
#define nsButton_h__
#include "nsWidget.h"
#include "nsIButton.h"
/**
* Native GTK+ button wrapper
*/
class nsButton : public nsWidget,
public nsIButton
{
public:
nsButton();
virtual ~nsButton();
NS_DECL_ISUPPORTS_INHERITED
// nsIButton part
NS_IMETHOD SetLabel(const nsString& aText);
NS_IMETHOD GetLabel(nsString& aBuffer);
virtual void SetFontNative(GdkFont *aFont);
protected:
NS_METHOD CreateNative(GtkObject *parentWindow);
virtual void InitCallbacks(char * aName = nsnull);
};
#endif // nsButton_h__

View File

@@ -0,0 +1,250 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsCheckButton.h"
#include "nsString.h"
NS_IMPL_ADDREF_INHERITED(nsCheckButton, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsCheckButton, nsWidget)
NS_IMPL_QUERY_INTERFACE2(nsCheckButton, nsICheckButton, nsIWidget)
//-------------------------------------------------------------------------
//
// nsCheckButton constructor
//
//-------------------------------------------------------------------------
nsCheckButton::nsCheckButton() : nsWidget() , nsICheckButton()
{
NS_INIT_REFCNT();
mLabel = nsnull;
mCheckButton = nsnull;
mState = PR_FALSE;
}
//-------------------------------------------------------------------------
//
// nsCheckButton destructor
//
//-------------------------------------------------------------------------
nsCheckButton::~nsCheckButton()
{
}
void
nsCheckButton::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCheckButton) {
mCheckButton = nsnull;
}
else if (aGtkWidget == mLabel) {
mLabel = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//-------------------------------------------------------------------------
//
// Create the native CheckButton widget
//
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::CreateNative(GtkObject *parentWindow)
{
mWidget = gtk_event_box_new();
mCheckButton = gtk_check_button_new();
gtk_container_add(GTK_CONTAINER(mWidget), mCheckButton);
gtk_widget_show(mCheckButton);
gtk_widget_set_name(mWidget, "nsCheckButton");
return NS_OK;
}
void nsCheckButton::InitCallbacks(char * aName)
{
InstallButtonPressSignal(mCheckButton);
InstallButtonReleaseSignal(mCheckButton);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_EXPOSURE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
// Add in destroy callback
gtk_signal_connect(GTK_OBJECT(mCheckButton),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
InstallSignal((GtkWidget *)mCheckButton,
(gchar *)"toggled",
GTK_SIGNAL_FUNC(nsCheckButton::ToggledSignal));
}
//-------------------------------------------------------------------------
//
// Set this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::SetState(const PRBool aState)
{
mState = aState;
if (mWidget && mCheckButton)
{
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mCheckButton);
item->active = (gboolean) mState;
gtk_widget_queue_draw(GTK_WIDGET(item));
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::GetState(PRBool& aState)
{
aState = mState;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set this Checkbox label
//
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::SetLabel(const nsString& aText)
{
if (mWidget) {
NS_ALLOC_STR_BUF(label, aText, 256);
if (mLabel) {
gtk_label_set(GTK_LABEL(mLabel), label);
} else {
mLabel = gtk_label_new(label);
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_container_add(GTK_CONTAINER(mCheckButton), mLabel);
gtk_widget_show(mLabel);
gtk_signal_connect(GTK_OBJECT(mLabel),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
NS_FREE_STR_BUF(label);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::GetLabel(nsString& aBuffer)
{
aBuffer.SetLength(0);
if (mWidget) {
char * text;
if (mLabel) {
gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.Append(text);
}
}
return NS_OK;
}
/* virtual */ void
nsCheckButton::OnToggledSignal(const gboolean aState)
{
// Untoggle the sonofabitch
if (mWidget && mCheckButton)
{
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mCheckButton);
item->active = !item->active;
gtk_widget_queue_draw(GTK_WIDGET(item));
}
}
//////////////////////////////////////////////////////////////////////
/* static */ gint
nsCheckButton::ToggledSignal(GtkWidget * aWidget,
gpointer aData)
{
NS_ASSERTION( nsnull != aWidget, "widget is null");
nsCheckButton * button = (nsCheckButton *) aData;
NS_ASSERTION( nsnull != button, "instance pointer is null");
button->OnToggledSignal(GTK_TOGGLE_BUTTON(aWidget)->active);
return PR_TRUE;
}
//////////////////////////////////////////////////////////////////////
// SetBackgroundColor for CheckButton
/*virtual*/
void nsCheckButton::SetBackgroundColorNative(GdkColor *aColorNor,
GdkColor *aColorBri,
GdkColor *aColorDark)
{
// use same style copy as SetFont
GtkStyle *style = gtk_style_copy(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0))->style);
style->bg[GTK_STATE_NORMAL]=*aColorNor;
// Mouse over button
style->bg[GTK_STATE_PRELIGHT]=*aColorBri;
// Button is down
style->bg[GTK_STATE_ACTIVE]=*aColorDark;
// other states too? (GTK_STATE_ACTIVE, GTK_STATE_PRELIGHT,
// GTK_STATE_SELECTED, GTK_STATE_INSENSITIVE)
gtk_widget_set_style(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0)), style);
// set style for eventbox too
gtk_widget_set_style(mWidget, style);
gtk_style_unref(style);
}

View File

@@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsCheckButton_h__
#define nsCheckButton_h__
#include "nsWidget.h"
#include "nsICheckButton.h"
/**
* Native GTK+ Checkbox wrapper
*/
class nsCheckButton : public nsWidget,
public nsICheckButton
{
public:
nsCheckButton();
virtual ~nsCheckButton();
NS_DECL_ISUPPORTS_INHERITED
// nsICheckButton part
NS_IMETHOD SetLabel(const nsString &aText);
NS_IMETHOD GetLabel(nsString &aBuffer);
NS_IMETHOD SetState(const PRBool aState);
NS_IMETHOD GetState(PRBool& aState);
virtual void OnToggledSignal(const gboolean aState);
protected:
NS_IMETHOD CreateNative(GtkObject *parentWindow);
virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
// Sets background for checkbutton
virtual void SetBackgroundColorNative(GdkColor *aColorNor,
GdkColor *aColorBri,
GdkColor *aColorDark);
GtkWidget *mLabel;
GtkWidget *mCheckButton;
// We need to maintain our own state to be in sync with the
// gecko check controlling frame.
PRBool mState;
private:
static gint ToggledSignal(GtkWidget * aWidget,
gpointer aData);
};
#endif // nsCheckButton_h__

View File

@@ -0,0 +1,872 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsClipboard.h"
#include "nsCOMPtr.h"
#include "nsISupportsArray.h"
#include "nsIClipboardOwner.h"
#include "nsITransferable.h" // kTextMime
#include "nsISupportsPrimitives.h"
#include "nsIWidget.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsWidgetsCID.h"
#include "nsXPIDLString.h"
#include "nsPrimitiveHelpers.h"
#include "nsVoidArray.h"
// The class statics:
GtkWidget* nsClipboard::sWidget = 0;
#if defined(DEBUG_mcafee) || defined(DEBUG_pavlov)
#define DEBUG_CLIPBOARD
#endif
enum {
TARGET_NONE,
TARGET_TEXT_PLAIN,
TARGET_TEXT_XIF,
TARGET_TEXT_UNICODE,
TARGET_TEXT_HTML,
TARGET_AOLMAIL,
TARGET_IMAGE_PNG,
TARGET_IMAGE_JPEG,
TARGET_IMAGE_GIF,
// compatibility types
TARGET_UTF8,
TARGET_UNKNOWN,
TARGET_LAST
};
static GdkAtom sSelTypes[TARGET_LAST];
//-------------------------------------------------------------------------
//
// nsClipboard constructor
//
//-------------------------------------------------------------------------
nsClipboard::nsClipboard() : nsBaseClipboard()
{
#ifdef DEBUG_CLIPBOARD
g_print("nsClipboard::nsClipboard()\n");
#endif /* DEBUG_CLIPBOARD */
//NS_INIT_REFCNT();
mIgnoreEmptyNotification = PR_FALSE;
mClipboardOwner = nsnull;
mTransferable = nsnull;
mSelectionData.data = nsnull;
mSelectionData.length = 0;
// initialize the widget, etc we're binding to
Init();
}
// XXX if GTK's internal code changes this isn't going to work
// copied from gtk code because it is a static function we can't get to it.
// need to bug owen taylor about getting this code public.
typedef struct _GtkSelectionTargetList GtkSelectionTargetList;
struct _GtkSelectionTargetList {
GdkAtom selection;
GtkTargetList *list;
};
static const char *gtk_selection_handler_key = "gtk-selection-handlers";
void __gtk_selection_target_list_remove (GtkWidget *widget)
{
GtkSelectionTargetList *sellist;
GList *tmp_list;
GList *lists;
lists = (GList*)gtk_object_get_data (GTK_OBJECT (widget), gtk_selection_handler_key);
tmp_list = lists;
while (tmp_list)
{
sellist = (GtkSelectionTargetList*)tmp_list->data;
gtk_target_list_unref (sellist->list);
g_free (sellist);
tmp_list = tmp_list->next;
}
g_list_free (lists);
gtk_object_set_data (GTK_OBJECT (widget), gtk_selection_handler_key, NULL);
}
//-------------------------------------------------------------------------
//
// nsClipboard destructor
//
//-------------------------------------------------------------------------
nsClipboard::~nsClipboard()
{
#ifdef DEBUG_CLIPBOARD
printf("nsClipboard::~nsClipboard()\n");
#endif /* DEBUG_CLIPBOARD */
// Remove all our event handlers:
if (sWidget &&
(gdk_selection_owner_get(GDK_SELECTION_PRIMARY) == sWidget->window))
gtk_selection_remove_all(sWidget);
// free the selection data, if any
if (mSelectionData.data != nsnull)
g_free(mSelectionData.data);
nsClipboard *cb = (nsClipboard*)gtk_object_get_data(GTK_OBJECT(sWidget), "cb");
if (cb != nsnull)
{
NS_RELEASE(cb);
gtk_object_remove_data(GTK_OBJECT(sWidget), "cb");
}
if (sWidget)
{
gtk_widget_destroy(sWidget);
sWidget = nsnull;
}
}
//
// GTK Weirdness!
// This is here in the hope of being able to call
// gtk_selection_add_targets(w, GDK_SELECTION_PRIMARY,
// targets,
// 1);
// instead of
// gtk_selection_add_target(sWidget,
// GDK_SELECTION_PRIMARY,
// GDK_SELECTION_TYPE_STRING,
// GDK_SELECTION_TYPE_STRING);
// but it turns out that this changes the whole gtk selection model;
// when calling add_targets copy uses selection_clear_event and the
// data structure needs to be filled in in a way that we haven't
// figured out; when using add_target copy uses selection_get and
// the data structure is already filled in as much as it needs to be.
// Some gtk internals wizard will need to solve this mystery before
// we can use add_targets().
//static GtkTargetEntry targets[] = {
// { "strings n stuff", GDK_SELECTION_TYPE_STRING, GDK_SELECTION_TYPE_STRING }
//};
//
//-------------------------------------------------------------------------
void nsClipboard::Init(void)
{
#ifdef DEBUG_CLIPBOARD
g_print("nsClipboard::Init\n");
#endif
sSelTypes[TARGET_NONE] = GDK_NONE;
sSelTypes[TARGET_TEXT_PLAIN] = gdk_atom_intern(kTextMime, FALSE);
sSelTypes[TARGET_TEXT_XIF] = gdk_atom_intern(kXIFMime, FALSE);
sSelTypes[TARGET_TEXT_UNICODE] = gdk_atom_intern(kUnicodeMime, FALSE);
sSelTypes[TARGET_UTF8] = gdk_atom_intern("UTF8", FALSE);
sSelTypes[TARGET_TEXT_HTML] = gdk_atom_intern(kHTMLMime, FALSE);
sSelTypes[TARGET_AOLMAIL] = gdk_atom_intern(kAOLMailMime, FALSE);
sSelTypes[TARGET_IMAGE_PNG] = gdk_atom_intern(kPNGImageMime, FALSE);
sSelTypes[TARGET_IMAGE_JPEG] = gdk_atom_intern(kJPEGImageMime, FALSE);
sSelTypes[TARGET_IMAGE_GIF] = gdk_atom_intern(kGIFImageMime, FALSE);
// compatibility with other apps
// create invisible widget to use for the clipboard
sWidget = gtk_invisible_new();
// add the clipboard pointer to the widget so we can get it.
gtk_object_set_data(GTK_OBJECT(sWidget), "cb", this);
NS_ADDREF_THIS();
// Handle selection requests if we called gtk_selection_add_target:
gtk_signal_connect(GTK_OBJECT(sWidget), "selection_get",
GTK_SIGNAL_FUNC(nsClipboard::SelectionGetCB),
nsnull);
// When someone else takes the selection away:
gtk_signal_connect(GTK_OBJECT(sWidget), "selection_clear_event",
GTK_SIGNAL_FUNC(nsClipboard::SelectionClearCB),
nsnull);
// Set up the paste handler:
gtk_signal_connect(GTK_OBJECT(sWidget), "selection_received",
GTK_SIGNAL_FUNC(nsClipboard::SelectionReceivedCB),
nsnull);
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsClipboard::SetNativeClipboardData()
{
mIgnoreEmptyNotification = PR_TRUE;
#ifdef DEBUG_CLIPBOARD
printf(" nsClipboard::SetNativeClipboardData()\n");
#endif /* DEBUG_CLIPBOARD */
// make sure we have a good transferable
if (nsnull == mTransferable) {
printf("nsClipboard::SetNativeClipboardData(): no transferable!\n");
return NS_ERROR_FAILURE;
}
// are we already the owner?
if (gdk_selection_owner_get(GDK_SELECTION_PRIMARY) == sWidget->window)
{
// if so, clear all the targets
__gtk_selection_target_list_remove(sWidget);
// gtk_selection_remove_all(sWidget);
}
// we arn't already the owner, so we will become it
gint have_selection = gtk_selection_owner_set(sWidget,
GDK_SELECTION_PRIMARY,
GDK_CURRENT_TIME);
if (have_selection == 0)
return NS_ERROR_FAILURE;
// get flavor list that includes all flavors that can be written (including ones
// obtained through conversion)
nsCOMPtr<nsISupportsArray> flavorList;
nsresult errCode = mTransferable->FlavorsTransferableCanExport ( getter_AddRefs(flavorList) );
if ( NS_FAILED(errCode) )
return NS_ERROR_FAILURE;
PRUint32 cnt;
flavorList->Count(&cnt);
for ( PRUint32 i=0; i<cnt; ++i )
{
nsCOMPtr<nsISupports> genericFlavor;
flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
nsCOMPtr<nsISupportsString> currentFlavor ( do_QueryInterface(genericFlavor) );
if ( currentFlavor ) {
nsXPIDLCString flavorStr;
currentFlavor->ToString(getter_Copies(flavorStr));
gint format = GetFormat(flavorStr);
// add these types as selection targets
RegisterFormat(format);
}
}
mIgnoreEmptyNotification = PR_FALSE;
return NS_OK;
}
void nsClipboard::AddTarget(GdkAtom aAtom)
{
gtk_selection_add_target(sWidget,
GDK_SELECTION_PRIMARY,
aAtom, aAtom);
}
gint nsClipboard::GetFormat(const char* aMimeStr)
{
gint type = TARGET_NONE;
nsCAutoString mimeStr ( CBufDescriptor(NS_CONST_CAST(char*,aMimeStr), PR_TRUE, PL_strlen(aMimeStr)+1) );
#ifdef DEBUG_CLIPBOARD
g_print(" nsClipboard::GetFormat(%s)\n", aMimeStr);
#endif
if (mimeStr.Equals(kTextMime)) {
type = TARGET_TEXT_PLAIN;
} else if (mimeStr.Equals("STRING")) {
type = TARGET_TEXT_PLAIN;
} else if (mimeStr.Equals(kXIFMime)) {
type = TARGET_TEXT_XIF;
} else if (mimeStr.Equals(kUnicodeMime)) {
type = TARGET_TEXT_UNICODE;
} else if (mimeStr.Equals(kHTMLMime)) {
type = TARGET_TEXT_HTML;
} else if (mimeStr.Equals(kAOLMailMime)) {
type = TARGET_AOLMAIL;
} else if (mimeStr.Equals(kPNGImageMime)) {
type = TARGET_IMAGE_PNG;
} else if (mimeStr.Equals(kJPEGImageMime)) {
type = TARGET_IMAGE_JPEG;
} else if (mimeStr.Equals(kGIFImageMime)) {
type = TARGET_IMAGE_GIF;
}
#ifdef WE_DO_DND
else if (mimeStr.Equals(kDropFilesMime)) {
format = CF_HDROP;
} else {
format = ::RegisterClipboardFormat(aMimeStr);
}
#endif
return type;
}
void nsClipboard::RegisterFormat(gint format)
{
#ifdef DEBUG_CLIPBOARD
g_print(" nsClipboard::RegisterFormat(%s)\n", gdk_atom_name(sSelTypes[format]));
#endif
/* when doing the selection_add_target, each case should have the same last parameter
which matches the case match */
switch(format)
{
case TARGET_TEXT_PLAIN:
// text/plain (default)
AddTarget(sSelTypes[format]);
// STRING (what X uses)
AddTarget(GDK_SELECTION_TYPE_STRING);
break;
case TARGET_TEXT_XIF:
// text/xif (default)
AddTarget(sSelTypes[format]);
break;
case TARGET_TEXT_UNICODE:
// text/unicode (default)
AddTarget(sSelTypes[format]);
// UTF8 (what X uses)
AddTarget(sSelTypes[TARGET_UTF8]);
break;
case TARGET_TEXT_HTML:
// text/html (default)
AddTarget(sSelTypes[format]);
break;
case TARGET_AOLMAIL:
// text/aolmail (default)
AddTarget(sSelTypes[format]);
break;
case TARGET_IMAGE_PNG:
// image/png (default)
AddTarget(sSelTypes[format]);
break;
case TARGET_IMAGE_JPEG:
// image/jpeg (default)
AddTarget(sSelTypes[format]);
break;
case TARGET_IMAGE_GIF:
// image/gif (default)
AddTarget(sSelTypes[format]);
break;
default:
// if we don't match something above, then just add it like its something we know about...
AddTarget(sSelTypes[format]);
}
}
PRBool nsClipboard::DoRealConvert(GdkAtom type)
{
#ifdef DEBUG_CLIPBOARD
g_print(" nsClipboard::DoRealConvert(%li)\n {\n", type);
#endif
int e = 0;
// Set a flag saying that we're blocking waiting for the callback:
mBlocking = PR_TRUE;
//
// ask X what kind of data we can get
//
#ifdef DEBUG_CLIPBOARD
g_print(" Doing real conversion of atom type '%s'\n", gdk_atom_name(type));
#endif
gtk_selection_convert(sWidget,
GDK_SELECTION_PRIMARY,
type,
GDK_CURRENT_TIME);
// Now we need to wait until the callback comes in ...
// i is in case we get a runaway (yuck).
#ifdef DEBUG_CLIPBOARD
printf(" Waiting for the callback... mBlocking = %d\n", mBlocking);
#endif /* DEBUG_CLIPBOARD */
for (e=0; mBlocking == PR_TRUE && e < 1000; ++e)
{
gtk_main_iteration_do(PR_TRUE);
}
#ifdef DEBUG_CLIPBOARD
g_print(" }\n");
#endif
if (mSelectionData.length > 0)
return PR_TRUE;
return PR_FALSE;
}
/* return PR_TRUE if we have converted or PR_FALSE if we havn't and need to keep being called */
PRBool nsClipboard::DoConvert(gint format)
{
#ifdef DEBUG_CLIPBOARD
g_print(" nsClipboard::DoConvert(%s)\n", gdk_atom_name(sSelTypes[format]));
#endif
/* when doing the selection_add_target, each case should have the same last parameter
which matches the case match */
PRBool r = PR_FALSE;
switch(format)
{
case TARGET_TEXT_PLAIN:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
r = DoRealConvert(GDK_SELECTION_TYPE_STRING);
if (r) return r;
break;
case TARGET_TEXT_XIF:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
break;
case TARGET_TEXT_UNICODE:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
r = DoRealConvert(sSelTypes[TARGET_UTF8]);
if (r) return r;
break;
case TARGET_TEXT_HTML:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
break;
case TARGET_AOLMAIL:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
break;
case TARGET_IMAGE_PNG:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
break;
case TARGET_IMAGE_JPEG:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
break;
case TARGET_IMAGE_GIF:
r = DoRealConvert(sSelTypes[format]);
if (r) return r;
break;
default:
g_print("DoConvert called with bogus format\n");
}
return r;
}
//-------------------------------------------------------------------------
//
// The blocking Paste routine
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable)
{
#ifdef DEBUG_CLIPBOARD
printf("nsClipboard::GetNativeClipboardData()\n");
#endif /* DEBUG_CLIPBOARD */
// make sure we have a good transferable
if (nsnull == aTransferable) {
printf(" GetNativeClipboardData: Transferable is null!\n");
return NS_ERROR_FAILURE;
}
// get flavor list that includes all acceptable flavors (including ones obtained through
// conversion)
nsCOMPtr<nsISupportsArray> flavorList;
nsresult errCode = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) );
if ( NS_FAILED(errCode) )
return NS_ERROR_FAILURE;
// Walk through flavors and see which flavor matches the one being pasted:
PRUint32 cnt;
flavorList->Count(&cnt);
nsCAutoString foundFlavor;
for ( PRUint32 i = 0; i < cnt; ++i ) {
nsCOMPtr<nsISupports> genericFlavor;
flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
nsCOMPtr<nsISupportsString> currentFlavor ( do_QueryInterface(genericFlavor) );
if ( currentFlavor ) {
nsXPIDLCString flavorStr;
currentFlavor->ToString ( getter_Copies(flavorStr) );
gint format = GetFormat(flavorStr);
if (DoConvert(format)) {
foundFlavor = flavorStr;
break;
}
}
}
#ifdef DEBUG_CLIPBOARD
printf(" Got the callback: '%s', %d\n",
mSelectionData.data, mSelectionData.length);
#endif /* DEBUG_CLIPBOARD */
// We're back from the callback, no longer blocking:
mBlocking = PR_FALSE;
//
// Now we have data in mSelectionData.data.
// We just have to copy it to the transferable.
//
#if 0
// pinkerton - we have the flavor already from above, so we don't need
// to re-derrive it.
nsString *name = new nsString((const char*)gdk_atom_name(mSelectionData.type));
int format = GetFormat(*name);
df->SetString((const char*)gdk_atom_name(sSelTypes[format]));
#endif
nsCOMPtr<nsISupports> genericDataWrapper;
nsPrimitiveHelpers::CreatePrimitiveForData ( foundFlavor, mSelectionData.data, mSelectionData.length, getter_AddRefs(genericDataWrapper) );
aTransferable->SetTransferData(foundFlavor,
genericDataWrapper,
mSelectionData.length);
//delete name;
// transferable is now copying the data, so we can free it.
// g_free(mSelectionData.data);
mSelectionData.data = nsnull;
mSelectionData.length = 0;
return NS_OK;
}
/**
* Called when the data from a paste comes in (recieved from gdk_selection_convert)
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
* @param aTime time the selection was requested
*/
void
nsClipboard::SelectionReceivedCB (GtkWidget *aWidget,
GtkSelectionData *aSelectionData,
guint aTime)
{
#ifdef DEBUG_CLIPBOARD
printf(" nsClipboard::SelectionReceivedCB\n {\n");
#endif /* DEBUG_CLIPBOARD */
nsClipboard *cb =(nsClipboard *)gtk_object_get_data(GTK_OBJECT(aWidget),
"cb");
if (!cb)
{
g_print("no clipboard found.. this is bad.\n");
return;
}
cb->SelectionReceiver(aWidget, aSelectionData);
#ifdef DEBUG_CLIPBOARD
g_print(" }\n");
#endif
}
/**
* local method (called from nsClipboard::SelectionReceivedCB)
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
*/
void
nsClipboard::SelectionReceiver (GtkWidget *aWidget,
GtkSelectionData *aSD)
{
gint type;
mBlocking = PR_FALSE;
if (aSD->length < 0)
{
printf(" Error retrieving selection: length was %d\n",
aSD->length);
return;
}
type = TARGET_NONE;
for (int i=0; i < TARGET_LAST; i++)
{
if (sSelTypes[i] == aSD->type)
{
type = i;
break;
}
}
switch (type)
{
case GDK_TARGET_STRING:
case TARGET_UTF8:
case TARGET_TEXT_PLAIN:
case TARGET_TEXT_XIF:
case TARGET_TEXT_UNICODE:
case TARGET_TEXT_HTML:
#ifdef DEBUG_CLIPBOARD
g_print(" Copying mSelectionData pointer -- ");
#endif
mSelectionData = *aSD;
mSelectionData.data = g_new(guchar, aSD->length + 1);
#ifdef DEBUG_CLIPBOARD
g_print(" Data = %s\n Length = %i\n", aSD->data, aSD->length);
#endif
memcpy(mSelectionData.data,
aSD->data,
aSD->length);
// Null terminate in case anyone cares,
// and so we can print the string for debugging:
mSelectionData.data[aSD->length] = '\0';
mSelectionData.length = aSD->length;
return;
default:
mSelectionData = *aSD;
mSelectionData.data = g_new(guchar, aSD->length + 1);
memcpy(mSelectionData.data,
aSD->data,
aSD->length);
mSelectionData.length = aSD->length;
return;
}
}
/**
* Some platforms support deferred notification for putting data on the clipboard
* This method forces the data onto the clipboard in its various formats
* This may be used if the application going away.
*
* @result NS_OK if successful.
*/
NS_IMETHODIMP nsClipboard::ForceDataToClipboard()
{
#ifdef DEBUG_CLIPBOARD
printf(" nsClipboard::ForceDataToClipboard()\n");
#endif /* DEBUG_CLIPBOARD */
// make sure we have a good transferable
if (nsnull == mTransferable) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
nsClipboard::HasDataMatchingFlavors(nsISupportsArray* aFlavorList, PRBool * outResult)
{
*outResult = PR_TRUE; // say we always do.
return NS_OK;
}
/**
* This is the callback which is called when another app
* requests the selection.
*
* @param widget The widget
* @param aSelectionData Selection data
* @param info Value passed in from the callback init
* @param time Time when the selection request came in
*/
void nsClipboard::SelectionGetCB(GtkWidget *widget,
GtkSelectionData *aSelectionData,
guint aInfo,
guint aTime)
{
#ifdef DEBUG_CLIPBOARD
printf("nsClipboard::SelectionGetCB\n");
#endif /* DEBUG_CLIPBOARD */
nsClipboard *cb = (nsClipboard *)gtk_object_get_data(GTK_OBJECT(widget),
"cb");
void *clipboardData;
PRUint32 dataLength;
nsresult rv;
// Make sure we have a transferable:
if (!cb->mTransferable) {
printf("Clipboard has no transferable!\n");
return;
}
#ifdef DEBUG_CLIPBOARD
g_print(" aInfo == %d -", aInfo);
#endif
char* dataFlavor = nsnull;
// switch aInfo (atom) to our enum
int type = (int)aInfo;
for (int i=0; i < TARGET_LAST; i++)
{
if (sSelTypes[i] == aInfo)
{
type = i;
break;
}
}
switch(type)
{
case GDK_TARGET_STRING:
case TARGET_TEXT_PLAIN:
dataFlavor = kTextMime;
break;
case TARGET_TEXT_XIF:
dataFlavor = kXIFMime;
break;
case TARGET_TEXT_UNICODE:
case TARGET_UTF8:
dataFlavor = kUnicodeMime;
break;
case TARGET_TEXT_HTML:
dataFlavor = kHTMLMime;
break;
case TARGET_AOLMAIL:
dataFlavor = kAOLMailMime;
break;
case TARGET_IMAGE_PNG:
dataFlavor = kPNGImageMime;
break;
case TARGET_IMAGE_JPEG:
dataFlavor = kJPEGImageMime;
break;
case TARGET_IMAGE_GIF:
dataFlavor = kGIFImageMime;
break;
default:
{
/* handle outside things */
}
}
#ifdef DEBUG_CLIPBOARD
g_print("- aInfo is for %s\n", gdk_atom_name(aInfo));
#endif
// Get data out of transferable.
nsCOMPtr<nsISupports> genericDataWrapper;
rv = cb->mTransferable->GetTransferData(dataFlavor,
getter_AddRefs(genericDataWrapper),
&dataLength);
nsPrimitiveHelpers::CreateDataFromPrimitive ( dataFlavor, genericDataWrapper, &clipboardData, dataLength );
if (NS_SUCCEEDED(rv) && clipboardData && dataLength > 0) {
size_t size = 1;
// find the number of bytes in the data for the below thing
// size_t size = sizeof((void*)((unsigned char)clipboardData[0]));
// g_print("************ ***************** ******************* %i\n", size);
gtk_selection_data_set(aSelectionData,
aInfo, size*8,
(unsigned char *)clipboardData,
dataLength);
nsCRT::free ( NS_REINTERPRET_CAST(char*, clipboardData) );
}
else
printf("Transferable didn't support the data flavor\n");
}
/**
* Called when another app requests selection ownership
*
* @param aWidget the widget
* @param aEvent the GdkEvent for the selection
* @param aData value passed in from the callback init
*/
void nsClipboard::SelectionClearCB(GtkWidget *aWidget,
GdkEventSelection *aEvent,
gpointer aData)
{
#ifdef DEBUG_CLIPBOARD
printf(" nsClipboard::SelectionClearCB\n");
#endif /* DEBUG_CLIPBOARD */
nsClipboard *cb = (nsClipboard *)gtk_object_get_data(GTK_OBJECT(aWidget),
"cb");
cb->EmptyClipboard();
}
/**
* The routine called when another app asks for the content of the selection
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
* @param aData value passed in from the callback init
*/
void
nsClipboard::SelectionRequestCB (GtkWidget *aWidget,
GtkSelectionData *aSelectionData,
gpointer aData)
{
#ifdef DEBUG_CLIPBOARD
printf(" nsClipboard::SelectionRequestCB\n");
#endif /* DEBUG_CLIPBOARD */
}
/**
* ...
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
* @param aData value passed in from the callback init
*/
void
nsClipboard::SelectionNotifyCB (GtkWidget *aWidget,
GtkSelectionData *aSelectionData,
gpointer aData)
{
#ifdef DEBUG_CLIPBOARD
printf(" nsClipboard::SelectionNotifyCB\n");
#endif /* DEBUG_CLIPBOARD */
}

View File

@@ -0,0 +1,132 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsClipboard_h__
#define nsClipboard_h__
#include "nsBaseClipboard.h"
#include <gtk/gtk.h>
#include <gtk/gtkinvisible.h>
class nsITransferable;
class nsIClipboardOwner;
class nsIWidget;
/**
* Native Gtk Clipboard wrapper
*/
class nsClipboard : public nsBaseClipboard
{
public:
nsClipboard();
virtual ~nsClipboard();
// nsIClipboard
NS_IMETHOD ForceDataToClipboard();
NS_IMETHOD HasDataMatchingFlavors(nsISupportsArray* aFlavorList, PRBool * outResult);
// invisible widget. also used by dragndrop
static GtkWidget *sWidget;
protected:
NS_IMETHOD SetNativeClipboardData();
NS_IMETHOD GetNativeClipboardData(nsITransferable * aTransferable);
PRBool mIgnoreEmptyNotification;
void AddTarget(GdkAtom aAtom);
gint GetFormat(const char* aMimeStr);
void RegisterFormat(gint format);
PRBool DoRealConvert(GdkAtom type);
PRBool DoConvert(gint format);
void Init(void);
// Used for communicating pasted data
// from the asynchronous X routines back to a blocking paste:
GtkSelectionData mSelectionData;
PRBool mBlocking;
void SelectionReceiver(GtkWidget *aWidget,
GtkSelectionData *aSD);
/**
* This is the callback which is called when another app
* requests the selection.
*
* @param widget The widget
* @param aSelectionData Selection data
* @param info Value passed in from the callback init
* @param time Time when the selection request came in
*/
static void SelectionGetCB(GtkWidget *aWidget,
GtkSelectionData *aSelectionData,
guint /*info*/,
guint /*time*/);
/**
* Called when another app requests selection ownership
*
* @param aWidget the widget
* @param aEvent the GdkEvent for the selection
* @param aData value passed in from the callback init
*/
static void SelectionClearCB(GtkWidget *aWidget,
GdkEventSelection *aEvent,
gpointer aData);
/**
* The routine called when another app asks for the content of the selection
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
* @param aData value passed in from the callback init
*/
static void SelectionRequestCB(GtkWidget *aWidget,
GtkSelectionData *aSelectionData,
gpointer data);
/**
* Called when the data from a paste comes in
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
* @param aTime time the selection was requested
*/
static void SelectionReceivedCB(GtkWidget *aWidget,
GtkSelectionData *aSelectionData,
guint aTime);
static void SelectionNotifyCB(GtkWidget *aWidget,
GtkSelectionData *aSelectionData,
gpointer aData);
};
#endif // nsClipboard_h__

View File

@@ -0,0 +1,357 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsComboBox.h"
#include "nsGUIEvent.h"
#include "nsString.h"
#define DBG 0
#define INITIAL_MAX_ITEMS 128
#define ITEMS_GROWSIZE 128
NS_IMPL_ADDREF_INHERITED(nsComboBox, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsComboBox, nsWidget)
NS_IMPL_QUERY_INTERFACE3(nsComboBox, nsIComboBox, nsIListWidget, nsIWidget)
//-------------------------------------------------------------------------
//
// nsComboBox constructor
//
//-------------------------------------------------------------------------
nsComboBox::nsComboBox() : nsWidget(), nsIListWidget(), nsIComboBox()
{
NS_INIT_REFCNT();
mMultiSelect = PR_FALSE;
mItems = nsnull;
mNumItems = 0;
}
//-------------------------------------------------------------------------
//
// nsComboBox:: destructor
//
//-------------------------------------------------------------------------
nsComboBox::~nsComboBox()
{
if (mItems) {
for (GList *items = mItems; items; items = (GList*) g_list_next(items)){
g_free(items->data);
}
g_list_free(mItems);
}
gtk_widget_destroy(mCombo);
}
void nsComboBox::InitCallbacks(char * aName)
{
InstallButtonPressSignal(mWidget);
InstallButtonReleaseSignal(mWidget);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_EXPOSURE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
}
//-------------------------------------------------------------------------
//
// initializer
//
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::SetMultipleSelection(PRBool aMultipleSelections)
{
mMultiSelect = aMultipleSelections;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// AddItemAt
//
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
{
NS_ALLOC_STR_BUF(val, aItem, 256);
mItems = g_list_insert( mItems, g_strdup(val), aPosition );
mNumItems++;
if (mCombo) {
gtk_combo_set_popdown_strings( GTK_COMBO( mCombo ), mItems );
}
NS_FREE_STR_BUF(val);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Finds an item at a postion
//
//-------------------------------------------------------------------------
PRInt32 nsComboBox::FindItem(nsString &aItem, PRInt32 aStartPos)
{
NS_ALLOC_STR_BUF(val, aItem, 256);
int i;
PRInt32 inx = -1;
GList *items = g_list_nth(mItems, aStartPos);
for(i=0; items != NULL; items = (GList *) g_list_next(items), i++ )
{
if(!strcmp(val, (gchar *) items->data))
{
inx = i;
break;
}
}
NS_FREE_STR_BUF(val);
return inx;
}
//-------------------------------------------------------------------------
//
// CountItems - Get Item Count
//
//-------------------------------------------------------------------------
PRInt32 nsComboBox::GetItemCount()
{
return (PRInt32)mNumItems;
}
//-------------------------------------------------------------------------
//
// Removes an Item at a specified location
//
//-------------------------------------------------------------------------
PRBool nsComboBox::RemoveItemAt(PRInt32 aPosition)
{
if (aPosition >= 0 && aPosition < mNumItems) {
g_free(g_list_nth(mItems, aPosition)->data);
mItems = g_list_remove_link(mItems, g_list_nth(mItems, aPosition));
mNumItems--;
if (mCombo) {
gtk_combo_set_popdown_strings(GTK_COMBO( mCombo ), mItems);
}
return PR_TRUE;
}
else
return PR_FALSE;
}
//-------------------------------------------------------------------------
//
// Removes an Item at a specified location
//
//-------------------------------------------------------------------------
PRBool nsComboBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
{
if (aPosition >= 0 && aPosition < mNumItems) {
anItem = (gchar *) g_list_nth(mItems, aPosition)->data;
return PR_TRUE;
}
return PR_FALSE;
}
//-------------------------------------------------------------------------
//
// Gets the selected of selected item
//
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::GetSelectedItem(nsString& aItem)
{
aItem.Truncate();
if (mCombo) {
aItem = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(mCombo)->entry));
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Gets the list of selected otems
//
//-------------------------------------------------------------------------
PRInt32 nsComboBox::GetSelectedIndex()
{
nsString nsstring;
GetSelectedItem(nsstring);
return FindItem(nsstring, 0);
}
//-------------------------------------------------------------------------
//
// SelectItem
//
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::SelectItem(PRInt32 aPosition)
{
GList *pos;
if (!mItems)
return NS_ERROR_FAILURE;
pos = g_list_nth(mItems, aPosition);
if (!pos)
return NS_ERROR_FAILURE;
if (mCombo) {
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(mCombo)->entry),
(gchar *) pos->data);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// GetSelectedCount
//
//-------------------------------------------------------------------------
PRInt32 nsComboBox::GetSelectedCount()
{
if (!mMultiSelect) {
PRInt32 inx = GetSelectedIndex();
return (inx == -1? 0 : 1);
} else {
return 0;
}
}
//-------------------------------------------------------------------------
//
// GetSelectedIndices
//
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
{
// this is an error
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
//
// Deselect
//
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::Deselect()
{
if (mMultiSelect) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Create the native GtkCombo widget
//
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::CreateNative(GtkObject *parentWindow)
{
mWidget = ::gtk_event_box_new();
::gtk_widget_set_name(mWidget, "nsComboBox");
mCombo = ::gtk_combo_new();
gtk_widget_show(mCombo);
/* make the stuff uneditable */
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(mCombo)->entry), PR_FALSE);
gtk_signal_connect(GTK_OBJECT(mCombo),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
gtk_signal_connect(GTK_OBJECT(GTK_COMBO(mCombo)->popwin),
"unmap",
GTK_SIGNAL_FUNC(UnmapSignal),
this);
gtk_container_add(GTK_CONTAINER(mWidget), mCombo);
return NS_OK;
}
void
nsComboBox::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCombo) {
mCombo = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
gint
nsComboBox::UnmapSignal(GtkWidget* aGtkWidget, nsComboBox* aCombo)
{
if (!aCombo) return PR_FALSE;
aCombo->OnUnmapSignal(aGtkWidget);
return PR_TRUE;
}
void
nsComboBox::OnUnmapSignal(GtkWidget * aWidget)
{
if (!aWidget) return;
// Generate a NS_CONTROL_CHANGE event and send it to the frame
nsGUIEvent event;
event.eventStructType = NS_GUI_EVENT;
nsPoint point(0,0);
InitEvent(event, NS_CONTROL_CHANGE, &point);
DispatchWindowEvent(&event);
}
//-------------------------------------------------------------------------
//
// Get handle for style
//
//-------------------------------------------------------------------------
/*virtual*/
void nsComboBox::SetFontNative(GdkFont *aFont)
{
GtkStyle *style = gtk_style_copy(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0))->style);
// gtk_style_copy ups the ref count of the font
gdk_font_unref (style->font);
style->font = aFont;
gdk_font_ref(style->font);
gtk_widget_set_style(GTK_BIN (mWidget)->child, style);
gtk_style_unref(style);
}

View File

@@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsComboBox_h__
#define nsComboBox_h__
#include "nsWidget.h"
#include "nsIComboBox.h"
/**
* Native GTK+ Listbox wrapper
*/
class nsComboBox : public nsWidget,
public nsIListWidget,
public nsIComboBox
{
public:
nsComboBox();
virtual ~nsComboBox();
NS_DECL_ISUPPORTS_INHERITED
// nsIComboBox interface
NS_IMETHOD AddItemAt(nsString &aItem, PRInt32 aPosition);
virtual PRInt32 FindItem(nsString &aItem, PRInt32 aStartPos);
virtual PRInt32 GetItemCount();
virtual PRBool RemoveItemAt(PRInt32 aPosition);
virtual PRBool GetItemAt(nsString& anItem, PRInt32 aPosition);
NS_IMETHOD GetSelectedItem(nsString& aItem);
virtual PRInt32 GetSelectedIndex();
NS_IMETHOD SelectItem(PRInt32 aPosition);
NS_IMETHOD Deselect() ;
// nsIComboBox interface
NS_IMETHOD SetMultipleSelection(PRBool aMultipleSelections);
PRInt32 GetSelectedCount();
NS_IMETHOD GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize);
virtual void SetFontNative(GdkFont *aFont);
protected:
NS_IMETHOD CreateNative(GtkObject *parentWindow);
virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
virtual void OnUnmapSignal(GtkWidget* aWidget);
static gint UnmapSignal(GtkWidget* aGtkWidget, nsComboBox* aCombo);
GtkWidget *mCombo; /* workaround for gtkcombo bug */
GList *mItems;
PRBool mMultiSelect;
int mNumItems;
};
#endif // nsComboBox_h__

View File

@@ -0,0 +1,744 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsContextMenu.h"
#include "nsIComponentManager.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsIMenuBar.h"
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsString.h"
#include "nsGtkEventHandler.h"
#include "nsCOMPtr.h"
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
//-------------------------------------------------------------------------
nsresult nsContextMenu::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(nsIMenu::GetIID())) {
*aInstancePtr = (void*)(nsIMenu*) this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIMenu*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIMenuListener::GetIID())) {
*aInstancePtr = (void*)(nsIMenuListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
//-------------------------------------------------------------------------
NS_IMPL_ADDREF(nsContextMenu)
NS_IMPL_RELEASE(nsContextMenu)
//-------------------------------------------------------------------------
//
// nsContextMenu constructor
//
//-------------------------------------------------------------------------
nsContextMenu::nsContextMenu()
{
NS_INIT_REFCNT();
mNumMenuItems = 0;
mMenu = nsnull;
mParent = nsnull;
mListener = nsnull;
mConstructCalled = PR_FALSE;
mDOMNode = nsnull;
mWebShell = nsnull;
mDOMElement = nsnull;
mAlignment = "topleft";
mAnchorAlignment = "none";
}
//-------------------------------------------------------------------------
//
// nsContextMenu destructor
//
//-------------------------------------------------------------------------
nsContextMenu::~nsContextMenu()
{
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::Create(nsISupports *aParent,
const nsString& anAlignment,
const nsString& anAnchorAlignment)
{
if(aParent)
{
nsIWidget *parent = nsnull;
aParent->QueryInterface(nsIWidget::GetIID(), (void**) &parent);
if(parent)
{
mParent = parent;
NS_RELEASE(parent);
}
}
mAlignment = anAlignment;
mAnchorAlignment = anAnchorAlignment;
mMenu = gtk_menu_new();
gtk_signal_connect (GTK_OBJECT (mMenu), "map",
GTK_SIGNAL_FUNC(menu_map_handler),
this);
gtk_signal_connect (GTK_OBJECT (mMenu), "unmap",
GTK_SIGNAL_FUNC(menu_unmap_handler),
this);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetParent(nsISupports*& aParent)
{
aParent = nsnull;
if (nsnull != mParent) {
return mParent->QueryInterface(kISupportsIID,
(void**)&aParent);
}
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddItem(nsISupports * aItem)
{
if(aItem)
{
nsIMenuItem * menuitem = nsnull;
aItem->QueryInterface(nsIMenuItem::GetIID(),
(void**)&menuitem);
if(menuitem)
{
AddMenuItem(menuitem); // nsMenu now owns this
NS_RELEASE(menuitem);
}
else
{
nsIMenu * menu = nsnull;
aItem->QueryInterface(nsIMenu::GetIID(),
(void**)&menu);
if(menu)
{
AddMenu(menu); // nsMenu now owns this
NS_RELEASE(menu);
}
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuItem(nsIMenuItem * aMenuItem)
{
GtkWidget *widget;
void *voidData;
aMenuItem->GetNativeData(voidData);
widget = GTK_WIDGET(voidData);
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
// XXX add aMenuItem to internal data structor list
// Need to be adding an nsISupports *, not nsIMenuItem *
nsISupports * supports = nsnull;
aMenuItem->QueryInterface(kISupportsIID,
(void**)&supports);
{
mMenuItemVoidArray.AppendElement(supports);
mNumMenuItems++;
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenu(nsIMenu * aMenu)
{
nsString Label;
GtkWidget *newmenu=nsnull;
char *labelStr;
void *voidData=NULL;
aMenu->GetLabel(Label);
labelStr = Label.ToNewCString();
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID,
nsnull,
nsIMenuItem::GetIID(),
(void**)&pnsMenuItem);
if (NS_OK == rv) {
nsISupports * supports = nsnull;
QueryInterface(kISupportsIID, (void**) &supports);
pnsMenuItem->Create(supports, labelStr, PR_FALSE); //PR_TRUE);
NS_RELEASE(supports);
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
void * menuitem = nsnull;
pnsMenuItem->GetNativeData(menuitem);
voidData = NULL;
aMenu->GetNativeData(&voidData);
newmenu = GTK_WIDGET(voidData);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), newmenu);
NS_RELEASE(pnsMenuItem);
}
nsCRT::free(labelStr);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddSeparator()
{
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(
kMenuItemCID, nsnull, nsIMenuItem::GetIID(), (void**)&pnsMenuItem);
if (NS_OK == rv) {
nsString tmp = "separator";
nsISupports * supports = nsnull;
QueryInterface(kISupportsIID, (void**) &supports);
pnsMenuItem->Create(supports, tmp, PR_TRUE);
NS_RELEASE(supports);
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
NS_RELEASE(pnsMenuItem);
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemCount(PRUint32 &aCount)
{
// this should be right.. does it need to be +1 ?
aCount = g_list_length(GTK_MENU_SHELL(mMenu)->children);
//g_print("nsMenu::GetItemCount = %i\n", aCount);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemAt(const PRUint32 aCount, nsISupports *& aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::InsertItemAt(const PRUint32 aCount, nsISupports * aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::InsertSeparator(const PRUint32 aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveItem(const PRUint32 aCount)
{
#if 0
// this may work here better than Removeall(), but i'm not sure how to test this one
nsISupports *item = mMenuItemVoidArray[aPos];
delete item;
mMenuItemVoidArray.RemoveElementAt(aPos);
#endif
/*
gtk_menu_shell_remove (GTK_MENU_SHELL (mMenu), item);
nsCRT::free(labelStr);
voidData = NULL;
aMenu->GetNativeData(&voidData);
newmenu = GTK_WIDGET(voidData);
gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
*/
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveAll()
{
//g_print("nsMenu::RemoveAll()\n");
#undef DEBUG_pavlov
#ifdef DEBUG_pavlov
// this doesn't work quite right, but this is about all that should really be needed
int i=0;
nsIMenu *menu = nsnull;
nsIMenuItem *menuitem = nsnull;
nsISupports *item = nsnull;
for (i=mMenuItemVoidArray.Count(); i>0; i--)
{
item = (nsISupports*)mMenuItemVoidArray[i-1];
if(nsnull != item)
{
if (NS_OK == item->QueryInterface(nsIMenuItem::GetIID(), (void**)&menuitem))
{
// we do this twice because we have to do it once for QueryInterface,
// then we want to get rid of it.
// g_print("remove nsMenuItem\n");
NS_RELEASE(menuitem);
NS_RELEASE(item);
menuitem = nsnull;
} else if (NS_OK == item->QueryInterface(nsIMenu::GetIID(), (void**)&menu)) {
#ifdef NOISY_MENUS
g_print("remove nsMenu\n");
#endif
NS_RELEASE(menu);
NS_RELEASE(item);
menu = nsnull;
}
// mMenuItemVoidArray.RemoveElementAt(i-1);
}
}
mMenuItemVoidArray.Clear();
return NS_OK;
#else
for (int i = mMenuItemVoidArray.Count(); i > 0; i--) {
if(nsnull != mMenuItemVoidArray[i-1]) {
nsIMenuItem * menuitem = nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(nsIMenuItem::GetIID(),
(void**)&menuitem);
if(menuitem) {
void *gtkmenuitem = nsnull;
menuitem->GetNativeData(gtkmenuitem);
if (gtkmenuitem) {
gtk_widget_ref(GTK_WIDGET(gtkmenuitem));
//gtk_widget_destroy(GTK_WIDGET(gtkmenuitem));
g_print("%p, %p\n",
GTK_WIDGET(GTK_CONTAINER(GTK_MENU_SHELL(GTK_MENU(mMenu)))),
GTK_WIDGET(GTK_WIDGET(gtkmenuitem)->parent));
gtk_container_remove(GTK_CONTAINER(GTK_MENU_SHELL(GTK_MENU(mMenu))),
GTK_WIDGET(gtkmenuitem));
}
} else {
nsIMenu * menu= nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(nsIMenu::GetIID(),
(void**)&menu);
if(menu)
{
void * gtkmenu = nsnull;
menu->GetNativeData(&gtkmenu);
if(gtkmenu){
g_print("nsMenu::RemoveAll() trying to remove nsMenu");
//gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
}
}
}
}
}
//g_print("end RemoveAll\n");
return NS_OK;
#endif
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetNativeData(void ** aData)
{
*aData = (void *)mMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuListener(nsIMenuListener * aMenuListener)
{
mListener = aMenuListener;
NS_ADDREF(mListener);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (aMenuListener == mListener) {
NS_IF_RELEASE(mListener);
}
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
if (nsnull != mListener) {
mListener->MenuSelected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
void menu_popup_position(GtkMenu *menu,
gint *x,
gint *y,
gpointer data)
{
nsContextMenu *cm = (nsContextMenu*)data;
*x = cm->GetX();
*y = cm->GetY();
}
nsEventStatus nsContextMenu::MenuSelected(const nsMenuEvent & aMenuEvent)
{
MenuConstruct(aMenuEvent,
mParent,
mDOMNode,
mWebShell);
//GtkWidget *parent = GTK_WIDGET(mParent->GetNativeData(NS_NATIVE_WIDGET));
gtk_menu_popup (GTK_MENU(mMenu),
(GtkWidget*)nsnull, (GtkWidget*)nsnull,
menu_popup_position,
this, 1, GDK_CURRENT_TIME);
/*
if (nsnull != mListener) {
mListener->MenuSelected(aMenuEvent);
}
*/
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsIMenuItem * nsContextMenu::FindMenuItem(nsIContextMenu * aMenu, PRUint32 aId)
{
return nsnull;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
if (nsnull != mListener) {
mListener->MenuDeselected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuConstruct(const nsMenuEvent &aMenuEvent,
nsIWidget *aParentWindow,
void *menuNode,
void *aWebShell)
{
//g_print("nsMenu::MenuConstruct called \n");
if(menuNode){
SetDOMNode((nsIDOMNode*)menuNode);
}
if(!aWebShell){
aWebShell = mWebShell;
}
// First open the menu.
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if (domElement)
domElement->SetAttribute("open", "true");
// Begin menuitem inner loop
nsCOMPtr<nsIDOMNode> menuitemNode;
((nsIDOMNode*)mDOMNode)->GetFirstChild(getter_AddRefs(menuitemNode));
unsigned short menuIndex = 0;
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
nsString menuitemName;
menuitemElement->GetNodeName(menuitemNodeType);
if (menuitemNodeType.Equals("menuitem")) {
// LoadMenuItem
LoadMenuItem(this,
menuitemElement,
menuitemNode,
menuIndex,
(nsIWebShell*)aWebShell);
} else if (menuitemNodeType.Equals("separator")) {
AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Load a submenu
LoadSubMenu(this, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
// Close the node.
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if (domElement)
domElement->RemoveAttribute("open");
//g_print("nsMenu::MenuDestruct called \n");
mConstructCalled = PR_FALSE;
RemoveAll();
return nsEventStatus_eIgnore;
}
//----------------------------------------
void nsContextMenu::LoadMenuItem(nsIMenu *pParentMenu,
nsIDOMElement *menuitemElement,
nsIDOMNode *menuitemNode,
unsigned short menuitemIndex,
nsIWebShell *aWebShell)
{
static const char* NS_STRING_TRUE = "true";
nsString disabled;
nsString menuitemName;
nsString menuitemCmd;
menuitemElement->GetAttribute(nsAutoString("disabled"), disabled);
menuitemElement->GetAttribute(nsAutoString("name"), menuitemName);
menuitemElement->GetAttribute(nsAutoString("cmd"), menuitemCmd);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID,
nsnull,
nsIMenuItem::GetIID(),
(void**)&pnsMenuItem);
if (NS_OK == rv) {
pnsMenuItem->Create(pParentMenu, menuitemName, PR_FALSE);
nsISupports * supports = nsnull;
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
pParentMenu->AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
if(disabled == NS_STRING_TRUE) {
pnsMenuItem->SetEnabled(PR_FALSE);
}
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
//return NS_ERROR_FAILURE;
return;
}
nsAutoString cmdAtom("onclick");
nsString cmdName;
domElement->GetAttribute(cmdAtom, cmdName);
pnsMenuItem->SetCommand(cmdName);
// DO NOT use passed in webshell because of messed up windows dynamic loading
// code.
pnsMenuItem->SetWebShell(mWebShell);
pnsMenuItem->SetDOMElement(domElement);
NS_RELEASE(pnsMenuItem);
}
return;
}
//----------------------------------------
void nsContextMenu::LoadSubMenu(nsIMenu *pParentMenu,
nsIDOMElement *menuElement,
nsIDOMNode *menuNode)
{
nsString menuName;
menuElement->GetAttribute(nsAutoString("name"), menuName);
//printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID,
nsnull,
nsIMenu::GetIID(),
(void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pParentMenu->QueryInterface(kISupportsIID, (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports); // Balance QI
// Set nsMenu Name
pnsMenu->SetLabel(menuName);
supports = nsnull;
pnsMenu->QueryInterface(kISupportsIID, (void**) &supports);
pParentMenu->AddItem(supports); // parent takes ownership
NS_RELEASE(supports);
pnsMenu->SetWebShell(mWebShell);
pnsMenu->SetDOMNode(menuNode);
/*
// Begin menuitem inner loop
unsigned short menuIndex = 0;
nsCOMPtr<nsIDOMNode> menuitemNode;
menuNode->GetFirstChild(getter_AddRefs(menuitemNode));
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
menuitemElement->GetNodeName(menuitemNodeType);
#ifdef DEBUG_saari
printf("Type [%s] %d\n", menuitemNodeType.ToNewCString(), menuitemNodeType.Equals("separator"));
#endif
if (menuitemNodeType.Equals("menuitem")) {
// Load a menuitem
LoadMenuItem(pnsMenu, menuitemElement, menuitemNode, menuIndex, mWebShell);
} else if (menuitemNodeType.Equals("separator")) {
pnsMenu->AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Add a submenu
LoadSubMenu(pnsMenu, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
*/
}
}
//----------------------------------------
void nsContextMenu::LoadMenuItem(nsIContextMenu *pParentMenu,
nsIDOMElement *menuitemElement,
nsIDOMNode *menuitemNode,
unsigned short menuitemIndex,
nsIWebShell *aWebShell)
{
}
//----------------------------------------
void nsContextMenu::LoadSubMenu(nsIContextMenu *pParentMenu,
nsIDOMElement *menuElement,
nsIDOMNode *menuNode)
{
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetLocation(PRInt32 aX, PRInt32 aY)
{
mX = aX;
mY = aY;
return NS_OK;
}
// local methods
gint nsContextMenu::GetX(void)
{
return mX;
}
gint nsContextMenu::GetY(void)
{
return mY;
}
// end silly local methods
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetDOMNode(nsIDOMNode *aMenuNode)
{
mDOMNode = aMenuNode;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetDOMElement(nsIDOMElement *aMenuElement)
{
mDOMElement = aMenuElement;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetWebShell(nsIWebShell *aWebShell)
{
mWebShell = aWebShell;
return NS_OK;
}

View File

@@ -0,0 +1,139 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsContextMenu_h__
#define nsContextMenu_h__
#include "nsIContextMenu.h"
#include "nsISupportsArray.h"
#include "nsVoidArray.h"
#include "nsIDOMElement.h"
#include "nsIWebShell.h"
class nsIMenuListener;
/**
* Native Win32 button wrapper
*/
class nsContextMenu : public nsIContextMenu, public nsIMenuListener
{
public:
nsContextMenu();
virtual ~nsContextMenu();
NS_DECL_ISUPPORTS
//nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menubarNode,
void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
// nsIMenu Methods
NS_IMETHOD Create(nsISupports * aParent,
const nsString& anAlignment,
const nsString& aAnchorAlign);
NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD AddItem(nsISupports * aItem);
NS_IMETHOD AddSeparator();
NS_IMETHOD GetItemCount(PRUint32 &aCount);
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem);
NS_IMETHOD RemoveItem(const PRUint32 aPos);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void** aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
//
NS_IMETHOD AddMenuItem(nsIMenuItem * aMenuItem);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
NS_IMETHOD InsertSeparator(const PRUint32 aCount);
NS_IMETHOD SetDOMNode(nsIDOMNode * menuNode);
NS_IMETHOD SetDOMElement(nsIDOMElement * menuElement);
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell);
NS_IMETHOD SetLocation(PRInt32 aX, PRInt32 aY);
gint GetX(void);
gint GetY(void);
protected:
nsIMenuBar * GetMenuBar(nsIMenu * aMenu);
nsIWidget * GetParentWidget();
char* GetACPString(nsString& aStr);
void LoadMenuItem(nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(nsIMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
void LoadMenuItem(nsIContextMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(nsIContextMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
nsIMenuItem * FindMenuItem(nsIContextMenu * aMenu, PRUint32 aId);
nsString mLabel;
PRUint32 mNumMenuItems;
GtkWidget *mMenu;
nsVoidArray mMenuItemVoidArray;
nsIWidget *mParent;
nsIMenuListener * mListener;
PRBool mConstructCalled;
nsIDOMNode * mDOMNode;
nsIWebShell * mWebShell;
nsIDOMElement * mDOMElement;
nsString mAlignment;
nsString mAnchorAlignment;
PRInt32 mX;
PRInt32 mY;
};
#endif // nsContextMenu_h__

View File

@@ -0,0 +1,592 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDragService.h"
#include "nsITransferable.h"
#include "nsString.h"
#include "nsClipboard.h"
#include "nsIRegion.h"
#include "nsVoidArray.h"
#include "nsISupportsPrimitives.h"
#include "nsPrimitiveHelpers.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsWidgetsCID.h"
NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService)
NS_IMPL_RELEASE_INHERITED(nsDragService, nsBaseDragService)
NS_IMPL_QUERY_INTERFACE2(nsDragService, nsIDragService, nsIDragSession)
#define DEBUG_DRAG 1
//-------------------------------------------------------------------------
//
// DragService constructor
//
//-------------------------------------------------------------------------
nsDragService::nsDragService()
{
NS_INIT_REFCNT();
mWidget = nsnull;
mNumFlavors = 0;
}
//-------------------------------------------------------------------------
//
// DragService destructor
//
//-------------------------------------------------------------------------
nsDragService::~nsDragService()
{
}
enum {
TARGET_STRING,
TARGET_ROOTWIN
};
static GtkTargetEntry target_table[] = {
{ "STRING", 0, TARGET_STRING },
{ "text/plain", 0, TARGET_STRING },
{ "application/x-rootwin-drop", 0, TARGET_ROOTWIN }
};
static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
NS_IMETHODIMP nsDragService::StartDragSession()
{
printf("nsDragService::StartDragSession()\n");
nsBaseDragService::StartDragSession();
/*
gtk_drag_source_set(mWidget,
GDK_MODIFIER_MASK,
targetlist,
mNumFlavors,
action);
*/
gtk_drag_source_set(mWidget,
GDK_MODIFIER_MASK,
target_table,
n_targets,
mActionType);
return NS_OK;
}
NS_IMETHODIMP nsDragService::EndDragSession()
{
printf("nsDragService::EndDragSession()\n");
nsBaseDragService::EndDragSession();
gtk_drag_source_unset(mWidget);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsDragService::InvokeDragSession (nsISupportsArray *aTransferableArray,
nsIScriptableRegion *aRegion,
PRUint32 aActionType)
{
mWidget = gtk_get_event_widget(gtk_get_current_event());
// add the flavors from the transferables. Cache this array for the send data proc
GtkTargetList *targetlist = RegisterDragItemsAndFlavors(aTransferableArray);
switch (aActionType)
{
case DRAGDROP_ACTION_NONE:
mActionType = GDK_ACTION_DEFAULT;
break;
case DRAGDROP_ACTION_COPY:
mActionType = GDK_ACTION_COPY;
break;
case DRAGDROP_ACTION_MOVE:
mActionType = GDK_ACTION_MOVE;
break;
case DRAGDROP_ACTION_LINK:
mActionType = GDK_ACTION_LINK;
break;
}
StartDragSession();
// XXX 3rd param ??? & last param should be a real event...
gtk_drag_begin(mWidget, targetlist, mActionType, 1, gtk_get_current_event());
#if 0
// we have to synthesize the native event because we may be called from JavaScript
// through XPConnect. In that case, we only have a DOM event and no way to
// get to the native event. As a consequence, we just always fake it.
Point globalMouseLoc;
::GetMouse(&globalMouseLoc);
::LocalToGlobal(&globalMouseLoc);
WindowPtr theWindow = nsnull;
if ( ::FindWindow(globalMouseLoc, &theWindow) != inContent ) {
// debugging sanity check
#ifdef NS_DEBUG
DebugStr("\pAbout to start drag, but FindWindow() != inContent; g");
#endif
}
EventRecord theEvent;
theEvent.what = mouseDown;
theEvent.message = reinterpret_cast<UInt32>(theWindow);
theEvent.when = 0;
theEvent.where = globalMouseLoc;
theEvent.modifiers = 0;
RgnHandle theDragRgn = ::NewRgn();
BuildDragRegion ( aDragRgn, globalMouseLoc, theDragRgn );
// register drag send proc which will call us back when asked for the actual
// flavor data (instead of placing it all into the drag manager)
::SetDragSendProc ( theDragRef, sDragSendDataUPP, this );
// start the drag. Be careful, mDragRef will be invalid AFTER this call (it is
// reset by the dragTrackingHandler).
::TrackDrag ( theDragRef, &theEvent, theDragRgn );
// clean up after ourselves
::DisposeRgn ( theDragRgn );
result = ::DisposeDrag ( theDragRef );
NS_ASSERTION ( result == noErr, "Error disposing drag" );
mDragRef = 0L;
mDataItems = nsnull;
return NS_OK;
#endif
return NS_OK;
}
GtkTargetList *
nsDragService::RegisterDragItemsAndFlavors(nsISupportsArray *inArray)
{
unsigned int numDragItems = 0;
inArray->Count(&numDragItems);
GtkTargetList *targetlist;
targetlist = gtk_target_list_new(nsnull, numDragItems);
for (unsigned int i = 0; i < numDragItems; ++i)
{
nsCOMPtr<nsISupports> genericItem;
inArray->GetElementAt (i, getter_AddRefs(genericItem));
nsCOMPtr<nsITransferable> currItem (do_QueryInterface(genericItem));
if (currItem)
{
nsCOMPtr<nsISupportsArray> flavorList;
if (NS_SUCCEEDED(currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList))))
{
flavorList->Count (&mNumFlavors);
for (PRUint32 flavorIndex = 0; flavorIndex < mNumFlavors; ++flavorIndex)
{
nsCOMPtr<nsISupports> genericWrapper;
flavorList->GetElementAt ( flavorIndex, getter_AddRefs(genericWrapper) );
nsCOMPtr<nsISupportsString> currentFlavor ( do_QueryInterface(genericWrapper) );
if ( currentFlavor )
{
nsXPIDLCString flavorStr;
currentFlavor->ToString ( getter_Copies(flavorStr) );
// register native flavors
GdkAtom atom = gdk_atom_intern(flavorStr, PR_TRUE);
gtk_target_list_add(targetlist, atom, 1, atom);
}
} // foreach flavor in item
} // if valid flavor list
} // if item is a transferable
} // foreach drag item
return targetlist;
}
/* return PR_TRUE if we have converted or PR_FALSE if we havn't and need to keep being called */
PRBool nsDragService::DoConvert(GdkAtom type)
{
#ifdef DEBUG_DRAG
g_print(" nsDragService::DoRealConvert(%li)\n {\n", type);
#endif
int e = 0;
// Set a flag saying that we're blocking waiting for the callback:
mBlocking = PR_TRUE;
//
// ask X what kind of data we can get
//
#ifdef DEBUG_DRAG
g_print(" Doing real conversion of atom type '%s'\n", gdk_atom_name(type));
#endif
gtk_selection_convert(mWidget,
GDK_SELECTION_PRIMARY,
type,
GDK_CURRENT_TIME);
// Now we need to wait until the callback comes in ...
// i is in case we get a runaway (yuck).
#ifdef DEBUG_DRAG
printf(" Waiting for the callback... mBlocking = %d\n", mBlocking);
#endif /* DEBUG_CLIPBOARD */
for (e=0; mBlocking == PR_TRUE && e < 1000; ++e)
{
gtk_main_iteration_do(PR_TRUE);
}
#ifdef DEBUG_DRAG
g_print(" }\n");
#endif
if (mSelectionData.length > 0)
return PR_TRUE;
return PR_FALSE;
}
#if 0
/**
* Called when the data from a drag comes in (recieved from gdk_selection_convert)
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
* @param aTime time the selection was requested
*/
void
nsDragService::SelectionReceivedCB (GtkWidget *aWidget,
GdkDragContext *aContext,
gint aX,
gint aY,
GtkSelectionData *aSelectionData,
guint aInfo,
guint aTime)
{
#ifdef DEBUG_DRAG
printf(" nsDragService::SelectionReceivedCB\n {\n");
#endif
nsDragService *ds =(nsDragSession *)gtk_object_get_data(GTK_OBJECT(aWidget),
"ds");
if (!cb)
{
g_print("no dragservice found.. this is bad.\n");
return;
}
ds->SelectionReceiver(aWidget, aSelectionData);
#ifdef DEBUG_DRAG
g_print(" }\n");
#endif
}
/**
* local method (called from nsClipboard::SelectionReceivedCB)
*
* @param aWidget the widget
* @param aSelectionData gtk selection stuff
*/
void
nsDragService::SelectionReceiver (GtkWidget *aWidget,
GtkSelectionData *aSD)
{
gint type;
mBlocking = PR_FALSE;
if (aSD->length < 0)
{
printf(" Error retrieving selection: length was %d\n",
aSD->length);
return;
}
switch (type)
{
case GDK_TARGET_STRING:
case TARGET_COMPOUND_TEXT:
case TARGET_TEXT_PLAIN:
case TARGET_TEXT_XIF:
case TARGET_TEXT_UNICODE:
case TARGET_TEXT_HTML:
#ifdef DEBUG_CLIPBOARD
g_print(" Copying mSelectionData pointer -- ");
#endif
mSelectionData = *aSD;
mSelectionData.data = g_new(guchar, aSD->length + 1);
#ifdef DEBUG_CLIPBOARD
g_print(" Data = %s\n Length = %i\n", aSD->data, aSD->length);
#endif
memcpy(mSelectionData.data,
aSD->data,
aSD->length);
// Null terminate in case anyone cares,
// and so we can print the string for debugging:
mSelectionData.data[aSD->length] = '\0';
mSelectionData.length = aSD->length;
return;
default:
mSelectionData = *aSD;
mSelectionData.data = g_new(guchar, aSD->length + 1);
memcpy(mSelectionData.data,
aSD->data,
aSD->length);
mSelectionData.length = aSD->length;
return;
}
}
#endif
//-------------------------------------------------------------------------
NS_IMETHODIMP nsDragService::GetNumDropItems (PRUint32 * aNumItems)
{
*aNumItems = 0;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32 anItem)
{
#ifdef DEBUG_DRAG
printf("nsClipboard::GetNativeClipboardData()\n");
#endif /* DEBUG_CLIPBOARD */
// make sure we have a good transferable
if (!aTransferable) {
printf(" GetData: Transferable is null!\n");
return NS_ERROR_FAILURE;
}
// get flavor list that includes all acceptable flavors (including ones obtained through
// conversion)
nsCOMPtr<nsISupportsArray> flavorList;
nsresult errCode = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) );
if ( NS_FAILED(errCode) )
return NS_ERROR_FAILURE;
// Walk through flavors and see which flavor matches the one being pasted:
PRUint32 cnt;
flavorList->Count(&cnt);
nsCAutoString foundFlavor;
for ( PRUint32 i = 0; i < cnt; ++i ) {
nsCOMPtr<nsISupports> genericFlavor;
flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
nsCOMPtr<nsISupportsString> currentFlavor (do_QueryInterface(genericFlavor));
if ( currentFlavor ) {
nsXPIDLCString flavorStr;
currentFlavor->ToString(getter_Copies(flavorStr));
if (DoConvert(gdk_atom_intern(flavorStr, 1))) {
foundFlavor = flavorStr;
break;
}
}
}
#ifdef DEBUG_CLIPBOARD
printf(" Got the callback: '%s', %d\n",
mSelectionData.data, mSelectionData.length);
#endif /* DEBUG_CLIPBOARD */
// We're back from the callback, no longer blocking:
mBlocking = PR_FALSE;
//
// Now we have data in mSelectionData.data.
// We just have to copy it to the transferable.
//
#if 0
// pinkerton - we have the flavor already from above, so we don't need
// to re-derrive it.
nsString *name = new nsString((const char*)gdk_atom_name(mSelectionData.type));
int format = GetFormat(*name);
df->SetString((const char*)gdk_atom_name(sSelTypes[format]));
#endif
nsCOMPtr<nsISupports> genericDataWrapper;
nsPrimitiveHelpers::CreatePrimitiveForData ( foundFlavor, mSelectionData.data, mSelectionData.length, getter_AddRefs(genericDataWrapper) );
aTransferable->SetTransferData(foundFlavor,
genericDataWrapper,
mSelectionData.length);
//delete name;
// transferable is now copying the data, so we can free it.
// g_free(mSelectionData.data);
mSelectionData.data = nsnull;
mSelectionData.length = 0;
gtk_drag_source_unset(mWidget);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
{
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsDragService::GetCurrentSession (nsIDragSession **aSession)
{
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
void
nsDragService::DragLeave (GtkWidget *widget,
GdkDragContext *context,
guint time)
{
g_print("leave\n");
//gHaveDrag = PR_FALSE;
}
//-------------------------------------------------------------------------
PRBool
nsDragService::DragMotion(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time)
{
g_print("drag motion\n");
GtkWidget *source_widget;
#if 0
if (!gHaveDrag) {
gHaveDrag = PR_TRUE;
}
#endif
source_widget = gtk_drag_get_source_widget (context);
g_print("motion, source %s\n", source_widget ?
gtk_type_name (GTK_OBJECT (source_widget)->klass->type) :
"unknown");
gdk_drag_status (context, context->suggested_action, time);
return PR_TRUE;
}
//-------------------------------------------------------------------------
PRBool
nsDragService::DragDrop(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time)
{
g_print("drop\n");
//gHaveDrag = PR_FALSE;
if (context->targets){
gtk_drag_get_data (widget, context,
GPOINTER_TO_INT (context->targets->data),
time);
return PR_TRUE;
}
return PR_FALSE;
}
//-------------------------------------------------------------------------
void
nsDragService::DragDataReceived (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time)
{
if ((data->length >= 0) && (data->format == 8)) {
g_print ("Received \"%s\"\n", (gchar *)data->data);
gtk_drag_finish (context, PR_TRUE, PR_FALSE, time);
return;
}
gtk_drag_finish (context, PR_FALSE, PR_FALSE, time);
}
//-------------------------------------------------------------------------
void
nsDragService::DragDataGet(GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data)
{
gtk_selection_data_set (selection_data,
selection_data->target,
8, (guchar *)"I'm Data!", 9);
}
//-------------------------------------------------------------------------
void
nsDragService::DragDataDelete(GtkWidget *widget,
GdkDragContext *context,
gpointer data)
{
g_print ("Delete the data!\n");
}

View File

@@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDragService_h__
#define nsDragService_h__
#include "nsBaseDragService.h"
#include <gtk/gtk.h>
/**
* Native GTK DragService wrapper
*/
class nsDragService : public nsBaseDragService
{
public:
nsDragService();
virtual ~nsDragService();
NS_DECL_ISUPPORTS_INHERITED
// nsIDragService
NS_IMETHOD InvokeDragSession (nsISupportsArray * anArrayTransferables,
nsIScriptableRegion * aRegion, PRUint32 aActionType);
NS_IMETHOD GetCurrentSession (nsIDragSession ** aSession);
// nsIDragSession
NS_IMETHOD GetData (nsITransferable * aTransferable, PRUint32 anItem);
NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems);
NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval);
NS_IMETHOD StartDragSession();
NS_IMETHOD EndDragSession();
GtkTargetList *RegisterDragItemsAndFlavors(nsISupportsArray *inArray);
protected:
PRBool DoConvert(GdkAtom type);
static PRBool gHaveDrag;
static void DragLeave(GtkWidget *widget,
GdkDragContext *context,
guint time);
static PRBool DragMotion(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time);
static PRBool DragDrop(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time);
static void DragDataReceived(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time);
static void DragDataGet(GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data);
static void DragDataDelete(GtkWidget *widget,
GdkDragContext *context,
gpointer data);
private:
GdkDragAction mActionType;
PRUint32 mNumFlavors;
GtkWidget *mWidget;
GdkDragContext *mDragContext;
GtkSelectionData mSelectionData;
PRBool mBlocking;
};
#endif // nsDragService_h__

View File

@@ -0,0 +1,304 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsFilePicker.h"
NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
//-------------------------------------------------------------------------
//
// nsFilePicker constructor
//
//-------------------------------------------------------------------------
nsFilePicker::nsFilePicker()
{
NS_INIT_REFCNT();
mWidget = nsnull;
mDisplayDirectory = nsnull;
mFilterMenu = nsnull;
mOptionMenu = nsnull;
mNumberOfFilters = 0;
}
//-------------------------------------------------------------------------
//
// nsFilePicker destructor
//
//-------------------------------------------------------------------------
nsFilePicker::~nsFilePicker()
{
if (mFilterMenu)
{
GtkWidget *menu_item;
GList *list = g_list_first(GTK_MENU_SHELL(mFilterMenu)->children);
for (;list; list = list->next)
{
menu_item = GTK_WIDGET(list->data);
gchar *data = (gchar*)gtk_object_get_data(GTK_OBJECT(menu_item), "filters");
if (data)
nsCRT::free(data);
}
}
gtk_widget_destroy(mWidget);
}
static void file_ok_clicked(GtkWidget *w, PRBool *ret)
{
g_print("user hit ok\n");
*ret = PR_TRUE;
gtk_main_quit();
}
static void file_cancel_clicked(GtkWidget *w, PRBool *ret)
{
g_print("user hit cancel\n");
*ret = PR_FALSE;
gtk_main_quit();
}
static void filter_item_activated(GtkWidget *w, gpointer data)
{
// nsFilePicker *f = (nsFilePicker*)data;
gchar *foo = (gchar*)gtk_object_get_data(GTK_OBJECT(w), "filters");
g_print("filter_item_activated(): %s\n", foo);
}
//-------------------------------------------------------------------------
//
// Show - Display the file dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::Show(PRInt16 *retval)
{
NS_ENSURE_ARG_POINTER(retval);
PRBool ret;
if (mWidget) {
// make things shorter
GtkFileSelection *fs = GTK_FILE_SELECTION(mWidget);
if (mNumberOfFilters != 0)
{
gtk_option_menu_set_menu(GTK_OPTION_MENU(mOptionMenu), mFilterMenu);
}
else
gtk_widget_hide(mOptionMenu);
#if 0
if (mDisplayDirectory)
gtk_file_selection_complete(fs, "/");
#endif
// gtk_window_set_modal(GTK_WINDOW(mWidget), PR_TRUE);
gtk_widget_show(mWidget);
// handle close, destroy, etc on the dialog
gtk_signal_connect(GTK_OBJECT(fs->ok_button), "clicked",
GTK_SIGNAL_FUNC(file_ok_clicked),
&ret);
gtk_signal_connect(GTK_OBJECT(fs->cancel_button), "clicked",
GTK_SIGNAL_FUNC(file_cancel_clicked),
&ret);
// start new loop. ret is set in the above callbacks.
gtk_main();
}
else {
ret = PR_FALSE;
}
if (ret)
*retval = returnOK;
else
*retval = returnCancel;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the list of filters
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetFilterList(PRInt32 aNumberOfFilters,
const PRUnichar **aTitles,
const PRUnichar **filters)
{
#if 0
GtkWidget *menu_item;
mNumberOfFilters = aNumberOfFilters;
mTitles = aTitles;
mFilters = aFilters;
mFilterMenu = gtk_menu_new();
for(unsigned int i=0; i < aNumberOfFilters; i++)
{
// we need *.{htm, html, xul, etc}
char *foo = aTitles[i].ToNewCString();
char *filters = aFilters[i].ToNewCString();
printf("%20s %s\n", foo, filters);
menu_item = gtk_menu_item_new_with_label(nsAutoCString(aTitles[i]));
gtk_object_set_data(GTK_OBJECT(menu_item), "filters", filters);
gtk_signal_connect(GTK_OBJECT(menu_item),
"activate",
GTK_SIGNAL_FUNC(filter_item_activated),
this);
gtk_menu_append(GTK_MENU(mFilterMenu), menu_item);
gtk_widget_show(menu_item);
nsCRT::free(foo);
}
#endif
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::GetFile(nsIFileSpec **aFile)
{
NS_ENSURE_ARG_POINTER(*aFile);
if (mWidget) {
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
nsCOMPtr<nsIFileSpec> fileSpec(do_CreateInstance("component://netscape/filespec"));
NS_ENSURE_TRUE(fileSpec, NS_ERROR_FAILURE);
fileSpec->SetNativePath(fn);
*aFile = fileSpec;
NS_ADDREF(*aFile);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetSelectedFilter(PRInt32 *aType)
{
NS_ENSURE_ARG_POINTER(aType);
*aType = mSelectedType;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the file + path
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetDefaultString(const PRUnichar *aString)
{
if (mWidget) {
gtk_file_selection_set_filename(GTK_FILE_SELECTION(mWidget),
(const gchar*)nsAutoCString(aString));
}
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::GetDefaultString(PRUnichar **aString)
{
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
//
// Set the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetDisplayDirectory(nsIFileSpec *aDirectory)
{
mDisplayDirectory = aDirectory;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetDisplayDirectory(nsIFileSpec **aDirectory)
{
*aDirectory = mDisplayDirectory;
NS_IF_ADDREF(*aDirectory);
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::Create(nsIDOMWindow *aParent,
const PRUnichar *aTitle,
PRInt16 aMode)
{
return nsBaseFilePicker::Create(aParent, aTitle, aMode);
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::CreateNative(nsIWidget *aParent,
const PRUnichar *aTitle,
PRInt16 aMode)
{
mWidget = gtk_file_selection_new((const gchar *)nsAutoCString(aTitle));
gtk_signal_connect(GTK_OBJECT(mWidget),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
gtk_button_box_set_layout(GTK_BUTTON_BOX(GTK_FILE_SELECTION(mWidget)->button_area), GTK_BUTTONBOX_SPREAD);
mOptionMenu = gtk_option_menu_new();
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(mWidget)->main_vbox), mOptionMenu, PR_FALSE, PR_FALSE, 0);
gtk_widget_show(mOptionMenu);
// Hide the file column for the folder case.
if (aMode == nsIFilePicker::modeGetFolder) {
gtk_widget_hide((GTK_FILE_SELECTION(mWidget)->file_list)->parent);
}
return NS_OK;
}
gint
nsFilePicker::DestroySignal(GtkWidget * aGtkWidget,
nsFilePicker* aWidget)
{
aWidget->OnDestroySignal(aGtkWidget);
return TRUE;
}
void
nsFilePicker::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mWidget) {
mWidget = nsnull;
}
}

View File

@@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef nsFilePicker_h__
#define nsFilePicker_h__
#include "nsBaseFilePicker.h"
#include <gtk/gtk.h>
/**
* Native GTK FileSelector wrapper
*/
class nsFilePicker : public nsBaseFilePicker
{
public:
nsFilePicker();
virtual ~nsFilePicker();
NS_DECL_ISUPPORTS
NS_DECL_NSIFILEPICKER
protected:
/* method from nsBaseFilePicker */
NS_IMETHOD CreateNative(nsIWidget *aParent,
const PRUnichar *aTitle,
PRInt16 aMode);
static gint DestroySignal(GtkWidget * aGtkWidget,
nsFilePicker* aWidget);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mWidget;
GtkWidget *mOptionMenu;
GtkWidget *mFilterMenu;
PRUint32 mNumberOfFilters;
const nsString* mTitles;
const nsString* mFilters;
nsString mDefault;
nsIFileSpec *mDisplayDirectory;
PRInt16 mSelectedType;
};
#endif // nsFilePicker_h__

View File

@@ -0,0 +1,322 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFileWidget.h"
#include "nsIToolkit.h"
NS_IMPL_ISUPPORTS1(nsFileWidget, nsIFileWidget)
//-------------------------------------------------------------------------
//
// nsFileWidget constructor
//
//-------------------------------------------------------------------------
nsFileWidget::nsFileWidget() : nsIFileWidget()
{
NS_INIT_REFCNT();
mWidget = nsnull;
mDisplayDirectory = nsnull;
mFilterMenu = nsnull;
mOptionMenu = nsnull;
mNumberOfFilters = 0;
}
//-------------------------------------------------------------------------
//
// nsFileWidget destructor
//
//-------------------------------------------------------------------------
nsFileWidget::~nsFileWidget()
{
if (mFilterMenu)
{
GtkWidget *menu_item;
GList *list = g_list_first(GTK_MENU_SHELL(mFilterMenu)->children);
for (;list; list = list->next)
{
menu_item = GTK_WIDGET(list->data);
gchar *data = (gchar*)gtk_object_get_data(GTK_OBJECT(menu_item), "filters");
if (data)
nsCRT::free(data);
}
}
gtk_widget_destroy(mWidget);
}
static void file_ok_clicked(GtkWidget *w, PRBool *ret)
{
g_print("user hit ok\n");
*ret = PR_TRUE;
gtk_main_quit();
}
static void file_cancel_clicked(GtkWidget *w, PRBool *ret)
{
g_print("user hit cancel\n");
*ret = PR_FALSE;
gtk_main_quit();
}
static void filter_item_activated(GtkWidget *w, gpointer data)
{
// nsFileWidget *f = (nsFileWidget*)data;
gchar *foo = (gchar*)gtk_object_get_data(GTK_OBJECT(w), "filters");
g_print("filter_item_activated(): %s\n", foo);
}
//-------------------------------------------------------------------------
//
// Show - Display the file dialog
//
//-------------------------------------------------------------------------
PRBool nsFileWidget::Show()
{
PRBool ret;
if (mWidget) {
// make things shorter
GtkFileSelection *fs = GTK_FILE_SELECTION(mWidget);
if (mNumberOfFilters != 0)
{
gtk_option_menu_set_menu(GTK_OPTION_MENU(mOptionMenu), mFilterMenu);
}
else
gtk_widget_hide(mOptionMenu);
#if 0
if (mDisplayDirectory)
gtk_file_selection_complete(fs, "/");
#endif
// gtk_window_set_modal(GTK_WINDOW(mWidget), PR_TRUE);
gtk_widget_show(mWidget);
// handle close, destroy, etc on the dialog
gtk_signal_connect(GTK_OBJECT(fs->ok_button), "clicked",
GTK_SIGNAL_FUNC(file_ok_clicked),
&ret);
gtk_signal_connect(GTK_OBJECT(fs->cancel_button), "clicked",
GTK_SIGNAL_FUNC(file_cancel_clicked),
&ret);
// start new loop. ret is set in the above callbacks.
gtk_main();
}
else {
ret = PR_FALSE;
}
return ret;
}
//-------------------------------------------------------------------------
//
// Set the list of filters
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFileWidget::SetFilterList(PRUint32 aNumberOfFilters,
const nsString aTitles[],
const nsString aFilters[])
{
GtkWidget *menu_item;
mNumberOfFilters = aNumberOfFilters;
mTitles = aTitles;
mFilters = aFilters;
mFilterMenu = gtk_menu_new();
for(unsigned int i=0; i < aNumberOfFilters; i++)
{
// we need *.{htm, html, xul, etc}
char *foo = aTitles[i].ToNewCString();
char *filters = aFilters[i].ToNewCString();
printf("%20s %s\n", foo, filters);
menu_item = gtk_menu_item_new_with_label(nsAutoCString(aTitles[i]));
gtk_object_set_data(GTK_OBJECT(menu_item), "filters", filters);
gtk_signal_connect(GTK_OBJECT(menu_item),
"activate",
GTK_SIGNAL_FUNC(filter_item_activated),
this);
gtk_menu_append(GTK_MENU(mFilterMenu), menu_item);
gtk_widget_show(menu_item);
nsCRT::free(foo);
}
return NS_OK;
}
NS_IMETHODIMP nsFileWidget::GetFile(nsFileSpec& aFile)
{
if (mWidget) {
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
aFile = fn; // Put the filename into the nsFileSpec instance.
}
return NS_OK;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFileWidget::GetSelectedType(PRInt16& theType)
{
theType = mSelectedType;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the file + path
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFileWidget::SetDefaultString(const nsString& aString)
{
if (mWidget) {
gtk_file_selection_set_filename(GTK_FILE_SELECTION(mWidget),
(const gchar*)nsAutoCString(aString));
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFileWidget::SetDisplayDirectory(const nsFileSpec& aDirectory)
{
mDisplayDirectory = aDirectory;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFileWidget::GetDisplayDirectory(nsFileSpec& aDirectory)
{
aDirectory = mDisplayDirectory;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFileWidget::Create(nsIWidget *aParent,
const nsString& aTitle,
nsFileDlgMode aMode,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
void *aInitData)
{
mMode = aMode;
mTitle.SetLength(0);
mTitle.Append(aTitle);
mWidget = gtk_file_selection_new((const gchar *)nsAutoCString(aTitle));
gtk_signal_connect(GTK_OBJECT(mWidget),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
gtk_button_box_set_layout(GTK_BUTTON_BOX(GTK_FILE_SELECTION(mWidget)->button_area), GTK_BUTTONBOX_SPREAD);
mOptionMenu = gtk_option_menu_new();
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(mWidget)->main_vbox), mOptionMenu, PR_FALSE, PR_FALSE, 0);
gtk_widget_show(mOptionMenu);
// Hide the file column for the folder case.
if (aMode == eMode_getfolder) {
gtk_widget_hide((GTK_FILE_SELECTION(mWidget)->file_list)->parent);
}
return NS_OK;
}
gint
nsFileWidget::DestroySignal(GtkWidget * aGtkWidget,
nsFileWidget* aWidget)
{
aWidget->OnDestroySignal(aGtkWidget);
return TRUE;
}
void
nsFileWidget::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mWidget) {
mWidget = nsnull;
}
}
nsFileDlgResults nsFileWidget::GetFile(nsIWidget *aParent,
const nsString &promptString,
nsFileSpec &theFileSpec)
{
Create(aParent, promptString, eMode_load, nsnull, nsnull);
if (Show() == PR_TRUE)
{
GetFile(theFileSpec);
return nsFileDlgResults_OK;
}
return nsFileDlgResults_Cancel;
}
nsFileDlgResults nsFileWidget::GetFolder(nsIWidget *aParent,
const nsString &promptString,
nsFileSpec &theFileSpec)
{
Create(aParent, promptString, eMode_getfolder, nsnull, nsnull);
if (Show() == PR_TRUE)
{
GetFile(theFileSpec);
return nsFileDlgResults_OK;
}
return nsFileDlgResults_Cancel;
}
nsFileDlgResults nsFileWidget::PutFile(nsIWidget *aParent,
const nsString &promptString,
nsFileSpec &theFileSpec)
{
Create(aParent, promptString, eMode_save, nsnull, nsnull);
if (Show() == PR_TRUE)
{
GetFile(theFileSpec);
return nsFileDlgResults_OK;
}
return nsFileDlgResults_Cancel;
}

View File

@@ -0,0 +1,102 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFileWidget_h__
#define nsFileWidget_h__
#include "nsIWidget.h"
#include "nsIFileWidget.h"
#include <gtk/gtk.h>
class nsIToolkit;
/**
* Native GTK FileSelector wrapper
*/
class nsFileWidget : public nsIFileWidget
{
public:
nsFileWidget();
virtual ~nsFileWidget();
NS_DECL_ISUPPORTS
// nsIWidget interface
NS_IMETHOD Create(nsIWidget *aParent,
const nsString& aTitle,
nsFileDlgMode aMode,
nsIDeviceContext *aContext = nsnull,
nsIAppShell *aAppShell = nsnull,
nsIToolkit *aToolkit = nsnull,
void *aInitData = nsnull);
// nsIFileWidget part
virtual PRBool Show();
NS_IMETHOD GetFile(nsFileSpec& aFile);
NS_IMETHOD SetDefaultString(const nsString& aFile);
NS_IMETHOD SetFilterList(PRUint32 aNumberOfFilters,
const nsString aTitles[],
const nsString aFilters[]);
NS_IMETHOD GetDisplayDirectory(nsFileSpec& aDirectory);
NS_IMETHOD SetDisplayDirectory(const nsFileSpec& aDirectory);
virtual nsFileDlgResults GetFile(nsIWidget *aParent,
const nsString &promptString,
nsFileSpec &theFileSpec);
virtual nsFileDlgResults GetFolder(nsIWidget *aParent,
const nsString &promptString,
nsFileSpec &theFileSpec);
virtual nsFileDlgResults PutFile(nsIWidget *aParent,
const nsString &promptString,
nsFileSpec &theFileSpec);
NS_IMETHOD GetSelectedType(PRInt16& theType);
protected:
static gint DestroySignal(GtkWidget * aGtkWidget,
nsFileWidget* aWidget);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mWidget;
nsString mTitle;
GtkWidget *mOptionMenu;
GtkWidget *mFilterMenu;
nsFileDlgMode mMode;
PRUint32 mNumberOfFilters;
const nsString* mTitles;
const nsString* mFilters;
nsString mDefault;
nsFileSpec mDisplayDirectory;
PRInt16 mSelectedType;
};
#endif // nsFileWidget_h__

View File

@@ -0,0 +1,395 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFontRetrieverService.h"
#include "nsIWidget.h"
#include <ctype.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "X11/Xlib.h"
#include "X11/Xutil.h"
#include "nsFont.h"
#include "nsVoidArray.h"
#include "nsFontSizeIterator.h"
NS_IMPL_ISUPPORTS2(nsFontRetrieverService, nsIFontRetrieverService, nsIFontNameIterator)
//----------------------------------------------------------
nsFontRetrieverService::nsFontRetrieverService()
{
NS_INIT_REFCNT();
mFontList = nsnull;
mSizeIter = nsnull;
mNameIterInx = 0;
}
//----------------------------------------------------------
nsFontRetrieverService::~nsFontRetrieverService()
{
if (nsnull != mFontList) {
for (PRInt32 i=0;i<mFontList->Count();i++) {
FontInfo * font = (FontInfo *)mFontList->ElementAt(i);
if (font->mSizes) {
delete font->mSizes;
}
delete font;
}
delete mFontList;
}
NS_IF_RELEASE(mSizeIter);
}
//----------------------------------------------------------
//-- nsIFontRetrieverService
//----------------------------------------------------------
NS_IMETHODIMP nsFontRetrieverService::CreateFontNameIterator( nsIFontNameIterator** aIterator )
{
if (nsnull == aIterator) {
return NS_ERROR_FAILURE;
}
if (nsnull == mFontList) {
LoadFontList();
}
*aIterator = this;
NS_ADDREF_THIS();
return NS_OK;
}
//----------------------------------------------------------
NS_IMETHODIMP nsFontRetrieverService::CreateFontSizeIterator( const nsString & aFontName,
nsIFontSizeIterator** aIterator )
{
// save value in case someone externally is using it
PRInt32 saveIterInx = mNameIterInx;
PRBool found = PR_FALSE;
Reset();
do {
nsAutoString name;
Get(&name);
if (name.Equals(aFontName)) {
found = PR_TRUE;
break;
}
} while (Advance() == NS_OK);
if (found) {
if (nsnull == mSizeIter) {
mSizeIter = new nsFontSizeIterator();
}
NS_ASSERTION( nsnull != mSizeIter, "nsFontSizeIterator instance pointer is null");
*aIterator = (nsIFontSizeIterator *)mSizeIter;
NS_ADDREF(mSizeIter);
FontInfo * fontInfo = (FontInfo *)mFontList->ElementAt(mNameIterInx);
mSizeIter->SetFontInfo(fontInfo);
mNameIterInx = saveIterInx;
return NS_OK;
}
mNameIterInx = saveIterInx;
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------
//-- nsIFontNameIterator
//----------------------------------------------------------
NS_IMETHODIMP nsFontRetrieverService::Reset()
{
mNameIterInx = 0;
return NS_OK;
}
//----------------------------------------------------------
NS_IMETHODIMP nsFontRetrieverService::Get( nsString* aFontName )
{
if (mNameIterInx < mFontList->Count()) {
FontInfo * fontInfo = (FontInfo *)mFontList->ElementAt(mNameIterInx);
*aFontName = fontInfo->mName;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------
NS_IMETHODIMP nsFontRetrieverService::Advance()
{
if (mNameIterInx < mFontList->Count()-1) {
mNameIterInx++;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
//------------------------------
static FontInfo * GetFontInfo(nsVoidArray * aFontList, char * aName)
{
nsAutoString name(aName);
PRInt32 i;
PRInt32 cnt = aFontList->Count();
for (i=0;i<cnt;i++) {
FontInfo * fontInfo = (FontInfo *)aFontList->ElementAt(i);
if (fontInfo->mName.Equals(name)) {
return fontInfo;
}
}
FontInfo * fontInfo = new FontInfo();
fontInfo->mName = aName;
//printf("Adding [%s]\n", aName);fflush(stdout);
fontInfo->mIsScalable = PR_FALSE; // X fonts aren't scalable right??
fontInfo->mSizes = nsnull;
aFontList->AppendElement(fontInfo);
return fontInfo;
}
//------------------------------
static void AddSizeToFontInfo(FontInfo * aFontInfo, PRInt32 aSize)
{
nsVoidArray * sizes;
if (nsnull == aFontInfo->mSizes) {
sizes = new nsVoidArray();
aFontInfo->mSizes = sizes;
} else {
sizes = aFontInfo->mSizes;
}
PRInt32 i;
PRInt32 cnt = sizes->Count();
for (i=0;i<cnt;i++) {
PRInt32 size = (int)sizes->ElementAt(i);
if (size == aSize) {
return;
}
}
sizes->AppendElement((void *)aSize);
}
//---------------------------------------------------
// XXX - Hack - Parts of this will need to be reworked
//
// This method does brute force parcing for 4 different formats:
//
// 1) The format -*-*-*-*-*-* etc.
// -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-8
//
// 2) Name-size format
// lucidasans-10
//
// 3) Name-style-size
// lucidasans-bold-10
//
// 4) Name only (implicit size)
// 6x13
//
//--------------------------------------------------
NS_IMETHODIMP nsFontRetrieverService::LoadFontList()
{
char * pattern = "*";
int nnames = 1024;
int available = nnames+1;
int i;
char **fonts;
XFontStruct *info;
if (nsnull == mFontList) {
mFontList = new nsVoidArray();
if (nsnull == mFontList) {
return NS_ERROR_FAILURE;
}
}
/* Get list of fonts matching pattern */
for (;;) {
// the following line is VERY slow to return
fonts = XListFontsWithInfo(GDK_DISPLAY(), pattern, nnames,
&available, &info);
if (fonts == NULL || available < nnames)
break;
XFreeFontInfo(fonts, info, available);
nnames = available * 2;
}
if (fonts == NULL) {
fprintf(stderr, "pattern \"%s\" unmatched\n", pattern);
return NS_ERROR_FAILURE;
}
#if 0 // debug
// print out all the retrieved fonts
printf("-----------------------------\n");
for (i=0; i<available; i++) {
printf("[%s]i\n", fonts[i]);
}
printf("-----------------------------\n");
#endif
// this code assumes all like fonts are grouped together
// currentName is the current name of the font we are gathering
// sizes for, when the name changes we create a new FontInfo object
// but it also takes into account fonts of similar names when it
// goes to add then and disregards duplicates
char buffer[1024];
char currentName[1024];
FontInfo * font = nsnull;
currentName[0] = 0;
for (i=0; i<available; i++) {
// This is kind of lame, but it will have to do for now
strcpy(buffer, fonts[i]);
// Start by checking to see if the name begins with a dash
char * ptr = buffer;
if (buffer[0] == '-') { //Format #1
PRInt32 cnt = 0;
// skip first two '-'
do {
if (*ptr == '-') cnt++;
ptr++;
} while (cnt < 2);
// find the dash at the end of the name
char * end = strchr(ptr, '-');
if (end) {
*end = 0;
// Check to see if we need to create a new FontInfo obj
// and set the currentName var to this guys font name
if (strcmp(currentName, ptr) || NULL == font) {
font = GetFontInfo(mFontList, ptr);
strcpy(currentName, ptr);
}
if (nsnull == font->mSizes) {
font->mSizes = new nsVoidArray();
}
ptr = end+1; // skip past the dash that was set to zero
cnt = 0;
// now skip ahead 4 dashes
do {
if (*ptr == '-') cnt++;
ptr++;
} while (cnt < 4);
// find the dash after the size
end = strchr(ptr, '-');
if (end) {
*end = 0;
PRInt32 size;
sscanf(ptr, "%d", &size);
AddSizeToFontInfo(font, size);
}
}
} else { // formats 2,3,4
// no leading dash means the start of the
// buffer is the start of the name
// this checks for a dash at the end of the font name
// which means there is a size at the end
char * end = strchr(buffer, '-');
if (end) { // Format 2,3
*end = 0;
// Check to see if we need to create a new FontInfo obj
// and set the currentName var to this guys font name
if (strcmp(currentName, buffer) || NULL == font) {
font = GetFontInfo(mFontList, buffer);
strcpy(currentName, buffer);
}
end++; // advance past the dash
// check to see if we have a number
ptr = end;
if (isalpha(*ptr)) { // Format 3
// skip until next dash
end = strchr(ptr, '-');
if (end) {
*end = 0;
ptr = end+1;
}
}
PRInt32 size;
// yes, it has a dash at the end so it must have the size
// check to see if the size is terminated by a dash
// it shouldn't be
char * end2 = strchr(ptr, '-');
if (end2) *end2 = 0; // put terminator at the dash
sscanf(end, "%d", &size);
AddSizeToFontInfo(font, size);
} else { // Format #4
// The font has an implicit size,
// so there is nothing to parse for size
// so we can't really do much here
// Check to see if we need to create a new FontInfo obj
// and set the currentName var to this guys font name
if (strcmp(currentName, buffer) || NULL == font) {
font = GetFontInfo(mFontList, buffer);
strcpy(currentName, buffer);
}
}
}
}
XFreeFontInfo(fonts, info, available);
return NS_OK;
}
//----------------------------------------------------------
NS_IMETHODIMP nsFontRetrieverService::IsFontScalable(const nsString & aFontName,
PRBool* aResult )
{
// save value in case someone externally is using it
PRInt32 saveIterInx = mNameIterInx;
PRBool found = PR_FALSE;
Reset();
do {
nsAutoString name;
Get(&name);
if (name.Equals(aFontName)) {
found = PR_TRUE;
break;
}
} while (Advance() == NS_OK);
if (found) {
FontInfo * fontInfo = (FontInfo *)mFontList->ElementAt(mNameIterInx);
*aResult = fontInfo->mIsScalable;
mNameIterInx = saveIterInx;
return NS_OK;
}
mNameIterInx = saveIterInx;
return NS_ERROR_FAILURE;
}

View File

@@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsFontRetrieverService
#define __nsFontRetrieverService
#include "nsIFontRetrieverService.h"
#include "nsIFontNameIterator.h"
class nsVoidArray;
class nsFontSizeIterator;
class nsFontRetrieverService: public nsIFontRetrieverService,
public nsIFontNameIterator
{
public:
nsFontRetrieverService();
virtual ~nsFontRetrieverService();
NS_DECL_ISUPPORTS
// nsIFontRetrieverService
NS_IMETHOD CreateFontNameIterator( nsIFontNameIterator** aIterator );
NS_IMETHOD CreateFontSizeIterator( const nsString & aFontName, nsIFontSizeIterator** aIterator );
NS_IMETHOD IsFontScalable( const nsString & aFontName, PRBool* aResult );
// nsIFontNameIterator
NS_IMETHOD Reset();
NS_IMETHOD Get( nsString* aFontName );
NS_IMETHOD Advance();
protected:
NS_IMETHOD LoadFontList();
nsVoidArray * mFontList;
PRInt32 mNameIterInx;
nsFontSizeIterator * mSizeIter;
};
#endif

View File

@@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFontSizeIterator.h"
#include "nsFont.h"
#include "nsVoidArray.h"
NS_IMPL_ADDREF(nsFontSizeIterator)
NS_IMPL_RELEASE(nsFontSizeIterator)
NS_IMPL_QUERY_INTERFACE(nsFontSizeIterator, nsIFontSizeIterator::GetIID())
//----------------------------------------------------------
nsFontSizeIterator::nsFontSizeIterator()
{
NS_INIT_REFCNT();
mFontInfo = nsnull;
mSizeIterInx = 0;
}
//----------------------------------------------------------
nsFontSizeIterator::~nsFontSizeIterator()
{
}
///----------------------------------------------------------
//-- nsIFontNameIterator
//----------------------------------------------------------
NS_IMETHODIMP nsFontSizeIterator::Reset()
{
mSizeIterInx = 0;
return NS_OK;
}
//----------------------------------------------------------
NS_IMETHODIMP nsFontSizeIterator::Get( double* aFontSize )
{
if (nsnull != mFontInfo->mSizes &&
mFontInfo->mSizes->Count() > 0 &&
mSizeIterInx < mFontInfo->mSizes->Count()) {
PRUint32 size = (PRUint32)mFontInfo->mSizes->ElementAt(mSizeIterInx);
*aFontSize = (double)size;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------
NS_IMETHODIMP nsFontSizeIterator::Advance()
{
if (nsnull != mFontInfo->mSizes &&
mFontInfo->mSizes->Count() > 0 &&
mSizeIterInx < mFontInfo->mSizes->Count()-2) {
mSizeIterInx++;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------
NS_IMETHODIMP nsFontSizeIterator::SetFontInfo( FontInfo * aFontInfo )
{
mFontInfo = aFontInfo;
return NS_OK;
}

View File

@@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsFontSizeIterator
#define __nsFontSizeIterator
#include "nsIFontSizeIterator.h"
#include "nsString.h"
class nsVoidArray;
typedef struct {
nsString mName;
PRBool mIsScalable;
nsVoidArray * mSizes;
} FontInfo;
class nsFontSizeIterator: public nsIFontSizeIterator {
public:
nsFontSizeIterator();
virtual ~nsFontSizeIterator();
NS_DECL_ISUPPORTS
// nsIFontSizeIterator
NS_IMETHOD Reset();
NS_IMETHOD Get( double* aFontSize );
NS_IMETHOD Advance();
// Native impl
NS_IMETHOD SetFontInfo( FontInfo * aFontInfo );
protected:
FontInfo * mFontInfo;
PRInt32 mSizeIterInx; // current index of iter
};
#endif

View File

@@ -0,0 +1,967 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsWidget.h"
#include "nsWindow.h"
#include "nsScrollbar.h"
#include "nsIFileWidget.h"
#include "nsGUIEvent.h"
#include "nsIMenu.h"
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsTextWidget.h"
#include "nsICharsetConverterManager.h"
#include "nsIPlatformCharset.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
#include "stdio.h"
#include "ctype.h"
#include "gtk/gtk.h"
#include "nsGtkEventHandler.h"
#include <gdk/gdkkeysyms.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef DEBUG_pavlov
//#define DEBUG_EVENTS 1
#endif
struct EventInfo {
nsWidget *widget; // the widget
nsRect *rect; // the rect
};
//==============================================================
void InitAllocationEvent(GtkAllocation *aAlloc,
gpointer p,
nsSizeEvent &anEvent,
PRUint32 aEventType)
{
anEvent.message = aEventType;
anEvent.widget = (nsWidget *) p;
anEvent.eventStructType = NS_SIZE_EVENT;
if (aAlloc != nsnull) {
// HACK
// nsRect *foo = new nsRect(aAlloc->x, aAlloc->y, aAlloc->width, aAlloc->height);
nsRect *foo = new nsRect(0, 0, aAlloc->width, aAlloc->height);
anEvent.windowSize = foo;
// anEvent.point.x = aAlloc->x;
// anEvent.point.y = aAlloc->y;
// HACK
anEvent.point.x = 0;
anEvent.point.y = 0;
anEvent.mWinWidth = aAlloc->width;
anEvent.mWinHeight = aAlloc->height;
}
anEvent.time = PR_IntervalNow();
}
//==============================================================
void InitConfigureEvent(GdkEventConfigure *aConf,
gpointer p,
nsSizeEvent &anEvent,
PRUint32 aEventType)
{
anEvent.message = aEventType;
anEvent.widget = (nsWidget *) p;
anEvent.eventStructType = NS_SIZE_EVENT;
if (aConf != nsnull) {
/* do we accually need to alloc a new rect, or can we just set the
current one */
nsRect *foo = new nsRect(aConf->x, aConf->y, aConf->width, aConf->height);
anEvent.windowSize = foo;
anEvent.point.x = aConf->x;
anEvent.point.y = aConf->y;
anEvent.mWinWidth = aConf->width;
anEvent.mWinHeight = aConf->height;
}
// this usually returns 0
anEvent.time = 0;
}
//==============================================================
void InitExposeEvent(GdkEventExpose *aGEE,
gpointer p,
nsPaintEvent &anEvent,
PRUint32 aEventType)
{
anEvent.message = aEventType;
anEvent.widget = (nsWidget *) p;
anEvent.eventStructType = NS_PAINT_EVENT;
if (aGEE != nsnull)
{
#ifdef DEBUG_EVENTS
g_print("expose event: x = %i , y = %i , w = %i , h = %i\n",
aGEE->area.x, aGEE->area.y,
aGEE->area.width, aGEE->area.height);
#endif
anEvent.point.x = aGEE->area.x;
anEvent.point.y = aGEE->area.y;
nsRect *rect = new nsRect(aGEE->area.x, aGEE->area.y,
aGEE->area.width, aGEE->area.height);
anEvent.rect = rect;
anEvent.time = gdk_event_get_time((GdkEvent*)aGEE);
}
}
//=============================================================
void UninitExposeEvent(GdkEventExpose *aGEE,
gpointer p,
nsPaintEvent &anEvent,
PRUint32 aEventType)
{
if (aGEE != nsnull) {
delete anEvent.rect;
}
}
struct nsKeyConverter {
int vkCode; // Platform independent key code
int keysym; // GDK keysym key code
};
//
// Netscape keycodes are defined in widget/public/nsGUIEvent.h
// GTK keycodes are defined in <gdk/gdkkeysyms.h>
//
struct nsKeyConverter nsKeycodes[] = {
{ NS_VK_CANCEL, GDK_Cancel },
{ NS_VK_BACK, GDK_BackSpace },
{ NS_VK_TAB, GDK_Tab },
{ NS_VK_TAB, GDK_ISO_Left_Tab },
{ NS_VK_CLEAR, GDK_Clear },
{ NS_VK_RETURN, GDK_Return },
{ NS_VK_SHIFT, GDK_Shift_L },
{ NS_VK_SHIFT, GDK_Shift_R },
{ NS_VK_CONTROL, GDK_Control_L },
{ NS_VK_CONTROL, GDK_Control_R },
{ NS_VK_ALT, GDK_Alt_L },
{ NS_VK_ALT, GDK_Alt_R },
{ NS_VK_PAUSE, GDK_Pause },
{ NS_VK_CAPS_LOCK, GDK_Caps_Lock },
{ NS_VK_ESCAPE, GDK_Escape },
{ NS_VK_SPACE, GDK_space },
{ NS_VK_PAGE_UP, GDK_Page_Up },
{ NS_VK_PAGE_DOWN, GDK_Page_Down },
{ NS_VK_END, GDK_End },
{ NS_VK_HOME, GDK_Home },
{ NS_VK_LEFT, GDK_Left },
{ NS_VK_UP, GDK_Up },
{ NS_VK_RIGHT, GDK_Right },
{ NS_VK_DOWN, GDK_Down },
{ NS_VK_PRINTSCREEN, GDK_Print },
{ NS_VK_INSERT, GDK_Insert },
{ NS_VK_DELETE, GDK_Delete },
{ NS_VK_MULTIPLY, GDK_KP_Multiply },
{ NS_VK_ADD, GDK_KP_Add },
{ NS_VK_SEPARATOR, GDK_KP_Separator },
{ NS_VK_SUBTRACT, GDK_KP_Subtract },
{ NS_VK_DECIMAL, GDK_KP_Decimal },
{ NS_VK_DIVIDE, GDK_KP_Divide },
{ NS_VK_RETURN, GDK_KP_Enter },
// NS doesn't have dash or equals distinct from the numeric keypad ones,
// so we'll use those for now. See bug 17008:
{ NS_VK_SUBTRACT, GDK_minus },
{ NS_VK_EQUALS, GDK_equal },
// and we don't have a single-quote symbol either:
{ NS_VK_QUOTE, GDK_apostrophe },
{ NS_VK_COMMA, GDK_comma },
{ NS_VK_PERIOD, GDK_period },
{ NS_VK_SLASH, GDK_slash },
{ NS_VK_BACK_SLASH, GDK_backslash },
{ NS_VK_BACK_QUOTE, GDK_grave },
{ NS_VK_OPEN_BRACKET, GDK_bracketleft },
{ NS_VK_CLOSE_BRACKET, GDK_bracketright },
{ NS_VK_QUOTE, GDK_quotedbl },
// Some shifted keys, see bug 15463.
// These should be subject to different keyboard mappings;
// how do we do that in gtk?
{ NS_VK_SEMICOLON, GDK_colon },
{ NS_VK_BACK_QUOTE, GDK_asciitilde },
{ NS_VK_COMMA, GDK_less },
{ NS_VK_PERIOD, GDK_greater },
{ NS_VK_SLASH, GDK_question },
{ NS_VK_1, GDK_exclam },
{ NS_VK_2, GDK_at },
{ NS_VK_3, GDK_numbersign },
{ NS_VK_4, GDK_dollar },
{ NS_VK_5, GDK_percent },
{ NS_VK_6, GDK_asciicircum },
{ NS_VK_7, GDK_ampersand },
{ NS_VK_8, GDK_asterisk },
{ NS_VK_9, GDK_parenleft },
{ NS_VK_0, GDK_parenright },
{ NS_VK_SUBTRACT, GDK_underscore },
{ NS_VK_EQUALS, GDK_plus }
};
void nsGtkWidget_InitNSKeyEvent(int aEventType, nsKeyEvent& aKeyEvent,
GtkWidget *w, gpointer p, GdkEventKey * event);
//==============================================================
// Input keysym is in gtk format; output is in NS_VK format
int nsPlatformToDOMKeyCode(GdkEventKey *aGEK)
{
int i;
int length = sizeof(nsKeycodes) / sizeof(struct nsKeyConverter);
int keysym = aGEK->keyval;
// First, try to handle alphanumeric input, not listed in nsKeycodes:
// most likely, more letters will be getting typed in than things in
// the key list, so we will look through these first.
// since X has different key symbols for upper and lowercase letters and
// mozilla does not, convert gdk's to mozilla's
if (keysym >= GDK_a && keysym <= GDK_z)
return keysym - GDK_a + NS_VK_A;
if (keysym >= GDK_A && keysym <= GDK_Z)
return keysym - GDK_A + NS_VK_A;
// numbers
if (keysym >= GDK_0 && keysym <= GDK_9)
return keysym - GDK_0 + NS_VK_0;
// keypad numbers
if (keysym >= GDK_KP_0 && keysym <= GDK_KP_9)
return keysym - GDK_KP_0 + NS_VK_NUMPAD0;
// misc other things
for (i = 0; i < length; i++) {
if (nsKeycodes[i].keysym == keysym)
return(nsKeycodes[i].vkCode);
}
// function keys
if (keysym >= GDK_F1 && keysym <= GDK_F24)
return keysym - GDK_F1 + NS_VK_F1;
#if defined(DEBUG_akkana) || defined(DEBUG_ftang)
printf("No match in nsPlatformToDOMKeyCode: keysym is 0x%x, string is %s\n", keysym, aGEK->string);
#endif
return((int)0);
}
//==============================================================
PRUint32 nsConvertCharCodeToUnicode(GdkEventKey* aGEK)
{
// For control chars, GDK sets string to be the actual ascii value.
// Map that to what nsKeyEvent wants, which currently --
// TEMPORARILY (the spec has changed and will be switched over
// when the tree opens for M11) --
// is the ascii for the actual event (e.g. 1 for control-a).
// This is only true for control chars; for alt chars, send the
// ascii for the key, i.e. a for alt-a.
if (aGEK->state & GDK_CONTROL_MASK)
{
if (aGEK->state & GDK_SHIFT_MASK)
return aGEK->string[0] + 'A' - 1;
else
return aGEK->string[0] + 'a' - 1;
}
// For now (obviously this will need to change for IME),
// only set a char code if the result is printable:
if (!isprint(aGEK->string[0]))
return 0;
// ALT keys in gdk give the upper case character in string,
// but we want the lower case char in char code
// unless shift was also pressed.
if (((aGEK->state & GDK_MOD1_MASK))
&& !(aGEK->state & GDK_SHIFT_MASK)
&& isupper(aGEK->string[0]))
return tolower(aGEK->string[0]);
//
// placeholder for something a little more interesting and correct
//
return aGEK->string[0];
}
//==============================================================
void InitKeyEvent(GdkEventKey *aGEK,
gpointer p,
nsKeyEvent &anEvent,
PRUint32 aEventType)
{
anEvent.message = aEventType;
anEvent.widget = (nsWidget *) p;
anEvent.eventStructType = NS_KEY_EVENT;
if (aGEK != nsnull) {
anEvent.keyCode = nsPlatformToDOMKeyCode(aGEK);
anEvent.charCode = 0;
anEvent.time = aGEK->time;
anEvent.isShift = (aGEK->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
anEvent.isControl = (aGEK->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
anEvent.isAlt = (aGEK->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
// XXX
anEvent.isMeta = PR_FALSE; //(aGEK->state & GDK_MOD2_MASK) ? PR_TRUE : PR_FALSE;
anEvent.point.x = 0;
anEvent.point.y = 0;
}
}
void InitKeyPressEvent(GdkEventKey *aGEK,
gpointer p,
nsKeyEvent &anEvent)
{
//
// init the basic event fields
//
anEvent.eventStructType = NS_KEY_EVENT;
anEvent.message = NS_KEY_PRESS;
anEvent.widget = (nsWidget*)p;
if (aGEK!=nsnull)
{
anEvent.isShift = (aGEK->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
anEvent.isControl = (aGEK->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
anEvent.isAlt = (aGEK->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
// XXX
anEvent.isMeta = PR_FALSE; //(aGEK->state & GDK_MOD2_MASK) ? PR_TRUE : PR_FALSE;
if(aGEK->length)
anEvent.charCode = nsConvertCharCodeToUnicode(aGEK);
else
anEvent.charCode = 0;
if (anEvent.charCode) {
anEvent.keyCode = 0;
anEvent.isShift = PR_FALSE;
} else
anEvent.keyCode = nsPlatformToDOMKeyCode(aGEK);
#if defined(DEBUG_akkana) || defined(DEBUG_pavlov) || defined (DEBUG_ftang)
printf("Key Press event: keyCode = 0x%x, char code = '%c'",
anEvent.keyCode, anEvent.charCode);
if (anEvent.isShift)
printf(" [shift]");
if (anEvent.isControl)
printf(" [ctrl]");
if (anEvent.isAlt)
printf(" [alt]");
if (anEvent.isMeta)
printf(" [meta]");
printf("\n");
#endif
anEvent.time = aGEK->time;
anEvent.point.x = 0;
anEvent.point.y = 0;
}
}
//=============================================================
void UninitKeyEvent(GdkEventKey *aGEK,
gpointer p,
nsKeyEvent &anEvent,
PRUint32 aEventType)
{
}
/*==============================================================
==============================================================
=============================================================
==============================================================*/
void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p)
{
nsWindow *widget = (nsWindow *)p;
nsSizeEvent event;
InitAllocationEvent(alloc, p, event, NS_SIZE);
NS_ADDREF(widget);
widget->OnResize(event);
NS_RELEASE(widget);
delete event.windowSize;
}
gint handle_expose_event(GtkWidget *w, GdkEventExpose *event, gpointer p)
{
if (event->type == GDK_NO_EXPOSE)
return PR_FALSE;
nsPaintEvent pevent;
InitExposeEvent(event, p, pevent, NS_PAINT);
nsWindow *win = (nsWindow *)p;
win->AddRef();
win->OnExpose(pevent);
win->Release();
UninitExposeEvent(event, p, pevent, NS_PAINT);
return PR_TRUE;
}
//==============================================================
void menu_item_activate_handler(GtkWidget *w, gpointer p)
{
// g_print("menu_item_activate_handler\n");
nsIMenuListener *menuListener = nsnull;
nsIMenuItem *menuItem = (nsIMenuItem *)p;
if (menuItem != nsnull) {
nsMenuEvent mevent;
mevent.message = NS_MENU_SELECTED;
mevent.eventStructType = NS_MENU_EVENT;
mevent.point.x = 0;
mevent.point.y = 0;
// mevent.widget = menuItem;
mevent.widget = nsnull;
menuItem->GetCommand(mevent.mCommand);
mevent.mMenuItem = menuItem;
mevent.time = PR_IntervalNow();
// FIXME - THIS SHOULD WORK. FIX EVENTS FOR XP CODE!!!!! (pav)
// nsEventStatus status;
// mevent.widget->DispatchEvent((nsGUIEvent *)&mevent, status);
menuItem->QueryInterface(nsIMenuListener::GetIID(), (void**)&menuListener);
if(menuListener) {
menuListener->MenuItemSelected(mevent);
NS_IF_RELEASE(menuListener);
}
}
}
//==============================================================
void menu_map_handler(GtkWidget *w, gpointer p)
{
nsIMenuListener *menuListener = nsnull;
nsIMenu *menu = (nsIMenu *)p;
if (menu != nsnull) {
nsMenuEvent mevent;
mevent.message = NS_MENU_SELECTED;
mevent.eventStructType = NS_MENU_EVENT;
mevent.point.x = 0;
mevent.point.y = 0;
mevent.widget = nsnull;
mevent.time = PR_IntervalNow();
menu->QueryInterface(nsIMenuListener::GetIID(), (void**)&menuListener);
if(menuListener) {
menuListener->MenuConstruct(
mevent,
nsnull, //parent window
nsnull, //menuNode
nsnull ); // webshell
NS_IF_RELEASE(menuListener);
}
}
}
//==============================================================
void menu_unmap_handler(GtkWidget *w, gpointer p)
{
nsIMenuListener *menuListener = nsnull;
nsIMenu *menu = (nsIMenu *)p;
if (menu != nsnull) {
nsMenuEvent mevent;
mevent.message = NS_MENU_SELECTED;
mevent.eventStructType = NS_MENU_EVENT;
mevent.point.x = 0;
mevent.point.y = 0;
mevent.widget = nsnull;
mevent.time = PR_IntervalNow();
menu->QueryInterface(nsIMenuListener::GetIID(), (void**)&menuListener);
if(menuListener) {
menuListener->MenuDestruct(mevent);
NS_IF_RELEASE(menuListener);
}
}
}
//==============================================================
void handle_scrollbar_value_changed(GtkAdjustment *adj, gpointer p)
{
nsScrollbar *widget = (nsScrollbar*) p;
nsScrollbarEvent sevent;
sevent.message = NS_SCROLLBAR_POS;
sevent.widget = (nsWidget *) p;
sevent.eventStructType = NS_SCROLLBAR_EVENT;
GdkWindow *win = (GdkWindow *)widget->GetNativeData(NS_NATIVE_WINDOW);
gdk_window_get_pointer(win, &sevent.point.x, &sevent.point.y, nsnull);
widget->AddRef();
widget->OnScroll(sevent, adj->value);
widget->Release();
/* FIXME we need to set point.* from the event stuff. */
#if 0
nsWindow * widgetWindow = (nsWindow *) p ;
XmScrollBarCallbackStruct * cbs = (XmScrollBarCallbackStruct*) call_data;
sevent.widget = (nsWindow *) p;
if (cbs->event != nsnull) {
sevent.point.x = cbs->event->xbutton.x;
sevent.point.y = cbs->event->xbutton.y;
} else {
sevent.point.x = 0;
sevent.point.y = 0;
}
sevent.time = 0; //XXX Implement this
switch (cbs->reason) {
case XmCR_INCREMENT:
sevent.message = NS_SCROLLBAR_LINE_NEXT;
break;
case XmCR_DECREMENT:
sevent.message = NS_SCROLLBAR_LINE_PREV;
break;
case XmCR_PAGE_INCREMENT:
sevent.message = NS_SCROLLBAR_PAGE_NEXT;
break;
case XmCR_PAGE_DECREMENT:
sevent.message = NS_SCROLLBAR_PAGE_PREV;
break;
case XmCR_DRAG:
sevent.message = NS_SCROLLBAR_POS;
break;
case XmCR_VALUE_CHANGED:
sevent.message = NS_SCROLLBAR_POS;
break;
default:
break;
}
#endif
}
static gint composition_start(GdkEventKey *aEvent, nsWindow *aWin,
nsEventStatus *aStatus) {
nsCompositionEvent compEvent;
compEvent.widget = (nsWidget*)aWin;
compEvent.point.x = 0;
compEvent.point.y = 0;
compEvent.time = aEvent->time;
compEvent.message = NS_COMPOSITION_START;
compEvent.eventStructType = NS_COMPOSITION_START;
compEvent.compositionMessage = NS_COMPOSITION_START;
aWin->DispatchEvent(&compEvent, *aStatus);
// set SpotLocation
aWin->SetXICSpotLocation(compEvent.theReply.mCursorPosition);
return PR_TRUE;
}
static gint composition_draw(GdkEventKey *aEvent, nsWindow *aWin,
nsIUnicodeDecoder *aDecoder,
nsEventStatus *aStatus) {
if (!aWin->mIMECompositionUniString) {
aWin->mIMECompositionUniStringSize = 128;
aWin->mIMECompositionUniString =
new PRUnichar[aWin->mIMECompositionUniStringSize];
}
PRUnichar *uniChar;
PRInt32 uniCharSize;
PRInt32 srcLen = aEvent->length;
for (;;) {
uniChar = aWin->mIMECompositionUniString;
uniCharSize = aWin->mIMECompositionUniStringSize - 1;
aDecoder->Convert((char*)aEvent->string, &srcLen, uniChar, &uniCharSize);
if (srcLen == aEvent->length &&
uniCharSize < aWin->mIMECompositionUniStringSize - 1) {
break;
}
aWin->mIMECompositionUniStringSize += 32;
aWin->mIMECompositionUniString =
new PRUnichar[aWin->mIMECompositionUniStringSize];
}
aWin->mIMECompositionUniString[uniCharSize] = 0;
nsTextEvent textEvent;
textEvent.message = NS_TEXT_EVENT;
textEvent.widget = (nsWidget*)aWin;
textEvent.time = aEvent->time;
textEvent.point.x = 0;
textEvent.point.y = 0;
textEvent.theText = aWin->mIMECompositionUniString;
textEvent.rangeCount = 0;
textEvent.rangeArray = nsnull;
textEvent.isShift = (aEvent->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
textEvent.isControl = (aEvent->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
textEvent.isAlt = (aEvent->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
// XXX
textEvent.isMeta = PR_FALSE; //(aEvent->state & GDK_MOD2_MASK) ? PR_TRUE : PR_FALSE;
textEvent.eventStructType = NS_TEXT_EVENT;
aWin->DispatchEvent(&textEvent, *aStatus);
aWin->SetXICSpotLocation(textEvent.theReply.mCursorPosition);
return True;
}
static gint composition_end(GdkEventKey *aEvent, nsWindow *aWin,
nsEventStatus *aStatus) {
nsCompositionEvent compEvent;
compEvent.widget = (nsWidget*)aWin;
compEvent.point.x = 0;
compEvent.point.y = 0;
compEvent.time = aEvent->time;
compEvent.message = NS_COMPOSITION_END;
compEvent.eventStructType = NS_COMPOSITION_END;
compEvent.compositionMessage = NS_COMPOSITION_END;
aWin->DispatchEvent(&compEvent, *aStatus);
return PR_TRUE;
}
static nsIUnicodeDecoder*
open_unicode_decoder(void) {
nsresult result = NS_ERROR_FAILURE;
nsIUnicodeDecoder *decoder = nsnull;
NS_WITH_SERVICE(nsIPlatformCharset, platform, NS_PLATFORMCHARSET_PROGID,
&result);
if (platform && NS_SUCCEEDED(result)) {
nsAutoString charset("");
result = platform->GetCharset(kPlatformCharsetSel_Menu, charset);
if (NS_FAILED(result) || (charset.Length() == 0)) {
charset = "ISO-8859-1"; // default
}
nsICharsetConverterManager* manager = nsnull;
nsresult res = nsServiceManager::
GetService(kCharsetConverterManagerCID,
nsCOMTypeInfo<nsICharsetConverterManager>::GetIID(),
(nsISupports**)&manager);
if (manager && NS_SUCCEEDED(res)) {
manager->GetUnicodeDecoder(&charset, &decoder);
nsServiceManager::ReleaseService(kCharsetConverterManagerCID, manager);
}
}
return decoder;
}
// GTK's text widget already does XIM, so we don't want to do this again
gint handle_key_press_event_for_text(GtkObject *w, GdkEventKey* event,
gpointer p)
{
nsKeyEvent kevent;
nsTextWidget* win = (nsTextWidget*)p;
// work around for annoying things.
if (event->keyval == GDK_Tab)
if (event->state & GDK_CONTROL_MASK)
if (event->state & GDK_MOD1_MASK)
return PR_FALSE;
// Don't pass shift, control and alt as key press events
if (event->keyval == GDK_Shift_L
|| event->keyval == GDK_Shift_R
|| event->keyval == GDK_Control_L
|| event->keyval == GDK_Control_R)
return PR_TRUE;
win->AddRef();
InitKeyEvent(event, p, kevent, NS_KEY_DOWN);
win->OnKey(kevent);
//
// Second, dispatch the Key event as a key press event w/ a Unicode
// character code. Note we have to check for modifier keys, since
// gtk returns a character value for them
//
InitKeyPressEvent(event,p, kevent);
win->OnKey(kevent);
win->Release();
if (w)
{
gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event");
}
return PR_TRUE;
}
// GTK's text widget already does XIM, so we don't want to do this again
gint handle_key_release_event_for_text(GtkObject *w, GdkEventKey* event,
gpointer p)
{
nsKeyEvent kevent;
nsTextWidget* win = (nsTextWidget*)p;
// Don't pass shift, control and alt as key release events
if (event->keyval == GDK_Shift_L
|| event->keyval == GDK_Shift_R
|| event->keyval == GDK_Control_L
|| event->keyval == GDK_Control_R)
return PR_TRUE;
InitKeyEvent(event, p, kevent, NS_KEY_UP);
win->AddRef();
win->OnKey(kevent);
win->Release();
if (w)
{
gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_release_event");
}
return PR_TRUE;
}
//==============================================================
gint handle_key_press_event(GtkObject *w, GdkEventKey* event, gpointer p)
{
nsKeyEvent kevent;
nsWindow* win = (nsWindow*)p;
// work around for annoying things.
if (event->keyval == GDK_Tab)
if (event->state & GDK_CONTROL_MASK)
if (event->state & GDK_MOD1_MASK)
return PR_FALSE;
// Don't pass shift, control and alt as key press events
if (event->keyval == GDK_Shift_L
|| event->keyval == GDK_Shift_R
|| event->keyval == GDK_Control_L
|| event->keyval == GDK_Control_R)
return PR_TRUE;
win->AddRef();
//
// First, dispatch the Key event as a virtual key down event
//
InitKeyEvent(event, p, kevent, NS_KEY_DOWN);
win->OnKey(kevent);
//
// Second, dispatch the Key event as a key press event w/ a Unicode
// character code. Note we have to check for modifier keys, since
// gtk returns a character value for them
//
if (event->length) {
static nsIUnicodeDecoder *decoder = nsnull;
if (!decoder) {
decoder = open_unicode_decoder();
}
if (decoder && (!kevent.keyCode)) {
nsEventStatus status;
composition_start(event, win, &status);
composition_draw(event, win, decoder, &status);
composition_end(event, win, &status);
} else {
InitKeyPressEvent(event,p, kevent);
win->OnKey(kevent);
nsEventStatus status;
composition_start(event, win, &status);
composition_end(event, win, &status);
}
} else { // for Home/End/Up/Down/Left/Right/PageUp/PageDown key
InitKeyPressEvent(event,p, kevent);
win->OnKey(kevent);
}
win->Release();
if (w)
{
gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event");
}
return PR_TRUE;
}
//==============================================================
gint handle_key_release_event(GtkObject *w, GdkEventKey* event, gpointer p)
{
// Don't pass shift, control and alt as key release events
if (event->keyval == GDK_Shift_L
|| event->keyval == GDK_Shift_R
|| event->keyval == GDK_Control_L
|| event->keyval == GDK_Control_R)
return PR_TRUE;
nsKeyEvent kevent;
InitKeyEvent(event, p, kevent, NS_KEY_UP);
nsWindow * win = (nsWindow *) p;
win->AddRef();
win->OnKey(kevent);
win->Release();
if (w)
{
gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_release_event");
}
return PR_TRUE;
}
//==============================================================
void
handle_gdk_event (GdkEvent *event, gpointer data)
{
GtkObject *object = nsnull;
if (event->any.window)
gdk_window_get_user_data (event->any.window, (void **)&object);
if (object != nsnull &&
GDK_IS_SUPERWIN (object))
{
// It was an event on one of our superwindows
nsWindow *window = (nsWindow *)gtk_object_get_data (object, "nsWindow");
if (gtk_grab_get_current () != nsnull)
{
// A GTK+ grab is in effect. Rewrite the event to point to
// our toplevel, and pass it through.
// XXX: We should actually translate the coordinates
gdk_window_unref (event->any.window);
event->any.window = GTK_WIDGET (window->GetMozArea())->window;
gdk_window_ref (event->any.window);
}
else
{
// Handle it ourselves.
switch (event->type)
{
case GDK_KEY_PRESS:
handle_key_press_event (NULL, &event->key, window);
break;
case GDK_KEY_RELEASE:
handle_key_release_event (NULL, &event->key, window);
break;
default:
window->HandleEvent (event);
}
return;
}
}
gtk_main_do_event (event);
}
//==============================================================
void
handle_xlib_shell_event(GdkSuperWin *superwin, XEvent *event, gpointer p)
{
nsWindow *window = (nsWindow *)p;
switch(event->xany.type) {
case ConfigureNotify:
window->HandleXlibConfigureNotifyEvent(event);
break;
default:
break;
}
}
//==============================================================
void
handle_xlib_bin_event(GdkSuperWin *superwin, XEvent *event, gpointer p)
{
nsWindow *window = (nsWindow *)p;
switch(event->xany.type) {
case Expose:
window->HandleXlibExposeEvent(event);
break;
case ButtonPress:
case ButtonRelease:
window->HandleXlibButtonEvent((XButtonEvent *)event);
break;
case MotionNotify:
window->HandleXlibMotionNotifyEvent((XMotionEvent *) event);
break;
case EnterNotify:
case LeaveNotify:
window->HandleXlibCrossingEvent((XCrossingEvent *) event);
break;
default:
break;
}
}
//==============================================================
gint nsGtkWidget_FSBCancel_Callback(GtkWidget *w, gpointer p)
{
#if 0
nsWindow *widgetWindow = (nsWindow*)gtk_object_get_user_data(GTK_OBJECT(w));
nsFileWidget * widgetWindow = (nsFileWidget *) p ;
if (p != nsnull) {
widgetWindow->OnCancel();
}
#endif
return PR_FALSE;
}
//==============================================================
gint nsGtkWidget_FSBOk_Callback(GtkWidget *w, gpointer p)
{
#if 0
nsWindow *widgetWindow = (nsWindow*)gtk_object_get_user_data(GTK_OBJECT(w));
nsFileWidget * widgetWindow = (nsFileWidget *) p;
if (p != nsnull) {
widgetWindow->OnOk();
}
#endif
return PR_FALSE;
}

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsGtkEventHandler_h
#define __nsGtkEventHandler_h
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "gdksuperwin.h"
class nsIWidget;
class nsIMenuItem;
class nsIMenu;
gint handle_configure_event(GtkWidget *w, GdkEventConfigure *conf, gpointer p);
void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p);
gint handle_expose_event(GtkWidget *w, GdkEventExpose *event, gpointer p);
gint handle_key_release_event_for_text(GtkObject *w, GdkEventKey* event, gpointer p);
gint handle_key_press_event_for_text(GtkObject *w, GdkEventKey* event, gpointer p);
gint handle_key_release_event(GtkObject *w, GdkEventKey* event, gpointer p);
gint handle_key_press_event(GtkObject *w, GdkEventKey* event, gpointer p);
void handle_scrollbar_value_changed(GtkAdjustment *adjustment, gpointer p);
void menu_item_activate_handler(GtkWidget *w, gpointer p);
void menu_map_handler(GtkWidget *w, gpointer p);
void menu_unmap_handler(GtkWidget *w, gpointer p);
//----------------------------------------------------
gint nsGtkWidget_FSBCancel_Callback(GtkWidget *w, gpointer p);
gint nsGtkWidget_FSBOk_Callback(GtkWidget *w, gpointer p);
//----------------------------------------------------
gint CheckButton_Toggle_Callback(GtkWidget *w, gpointer p);
gint nsGtkWidget_RadioButton_ArmCallback(GtkWidget *w, gpointer p);
gint nsGtkWidget_RadioButton_DisArmCallback(GtkWidget *w, gpointer p);
gint nsGtkWidget_Text_Callback(GtkWidget *w, GdkEventKey* event, gpointer p);
gint nsGtkWidget_Expose_Callback(GtkWidget *w, gpointer p);
gint nsGtkWidget_Refresh_Callback(gpointer call_data);
void handle_xlib_shell_event(GdkSuperWin *superwin, XEvent *event, gpointer p);
void handle_xlib_bin_event(GdkSuperWin *superwin, XEvent *event, gpointer p);
void handle_gdk_event (GdkEvent *event, gpointer data);
#endif // __nsGtkEventHandler.h

View File

@@ -0,0 +1,213 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <unistd.h>
#include <string.h>
#include "nsGtkUtils.h"
#include <gdk/gdkx.h>
#include <gdk/gdkprivate.h>
#if defined(__osf__) && !defined(_XOPEN_SOURCE_EXTENDED)
/*
** DEC's compiler requires _XOPEN_SOURCE_EXTENDED to be defined in
** order for it to see the prototype for usleep in unistd.h, but if
** we define that the build breaks long before getting here. So
** put the prototype here explicitly.
*/
int usleep(useconds_t);
#endif
#if defined(__QNX__)
#define usleep(s) sleep(s)
#endif
//////////////////////////////////////////////////////////////////
#if 0
/* staitc */ gint
nsGtkUtils::gdk_query_pointer(GdkWindow * window,
gint * x_out,
gint * y_out)
{
g_return_val_if_fail(NULL != window, FALSE);
g_return_val_if_fail(NULL != x_out, FALSE);
g_return_val_if_fail(NULL != y_out, FALSE);
Window root;
Window child;
int rootx, rooty;
int winx = 0;
int winy = 0;
unsigned int xmask = 0;
gint result = FALSE;
*x_out = -1;
*y_out = -1;
result = XQueryPointer(GDK_WINDOW_XDISPLAY(window),
GDK_WINDOW_XWINDOW(window),
&root,
&child,
&rootx,
&rooty,
&winx,
&winy,
&xmask);
if (result)
{
*x_out = rootx;
*y_out = rooty;
}
return result;
}
#endif
//////////////////////////////////////////////////////////////////
/* static */ void
nsGtkUtils::gtk_widget_set_color(GtkWidget * widget,
GtkRcFlags flags,
GtkStateType state,
GdkColor * color)
{
GtkRcStyle * rc_style;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (color != NULL);
g_return_if_fail (flags == 0);
rc_style = (GtkRcStyle *) gtk_object_get_data (GTK_OBJECT (widget),
"modify-style");
if (!rc_style)
{
rc_style = gtk_rc_style_new ();
gtk_widget_modify_style (widget, rc_style);
gtk_object_set_data (GTK_OBJECT (widget), "modify-style", rc_style);
}
if (flags & GTK_RC_FG)
{
rc_style->color_flags[state] = GtkRcFlags(rc_style->color_flags[state] | GTK_RC_FG);
rc_style->fg[state] = *color;
}
if (flags & GTK_RC_BG)
{
rc_style->color_flags[state] = GtkRcFlags(rc_style->color_flags[state] | GTK_RC_BG);
rc_style->bg[state] = *color;
}
if (flags & GTK_RC_TEXT)
{
rc_style->color_flags[state] = GtkRcFlags(rc_style->color_flags[state] | GTK_RC_TEXT);
rc_style->text[state] = *color;
}
if (flags & GTK_RC_BASE)
{
rc_style->color_flags[state] = GtkRcFlags(rc_style->color_flags[state] | GTK_RC_BASE);
rc_style->base[state] = *color;
}
}
//////////////////////////////////////////////////////////////////
/* static */ GdkModifierType
nsGtkUtils::gdk_keyboard_get_modifiers()
{
GdkModifierType m = (GdkModifierType) 0;
gdk_window_get_pointer(NULL,NULL,NULL,&m);
return m;
}
//////////////////////////////////////////////////////////////////
/* static */ void
nsGtkUtils::gdk_window_flash(GdkWindow * aGdkWindow,
unsigned int aTimes,
unsigned long aInterval,
GdkRectangle * aArea)
{
gint x;
gint y;
gint width;
gint height;
guint i;
GdkGC * gc = 0;
GdkColor white;
gdk_window_get_geometry(aGdkWindow,
NULL,
NULL,
&width,
&height,
NULL);
gdk_window_get_origin (aGdkWindow,
&x,
&y);
gc = gdk_gc_new(GDK_ROOT_PARENT());
white.pixel = WhitePixel(gdk_display,DefaultScreen(gdk_display));
gdk_gc_set_foreground(gc,&white);
gdk_gc_set_function(gc,GDK_XOR);
gdk_gc_set_subwindow(gc,GDK_INCLUDE_INFERIORS);
/*
* If an area is given, use that. Notice how out of whack coordinates
* and dimentsions are not checked!!!
*/
if (aArea)
{
x += aArea->x;
y += aArea->y;
width = aArea->width;
height = aArea->height;
}
/*
* Need to do this twice so that the XOR effect can replace
* the original window contents.
*/
for (i = 0; i < aTimes * 2; i++)
{
gdk_draw_rectangle(GDK_ROOT_PARENT(),
gc,
TRUE,
x,
y,
width,
height);
gdk_flush();
usleep(aInterval);
}
gdk_gc_destroy(gc);
}
//////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsGtkUtils_h
#define __nsGtkUtils_h
#include <gtk/gtk.h>
struct nsGtkUtils
{
//
// Wrapper for XQueryPointer
//
#if 0
static gint gdk_query_pointer(GdkWindow * window,
gint * x_out,
gint * y_out);
#endif
//
// Change a widget's background
//
// flags isa bit mask of the following bits:
//
// GTK_RC_FG
// GTK_RC_BG
// GTK_RC_TEXT
// GTK_RC_BASE
//
// state is an enum:
//
// GTK_STATE_NORMAL,
// GTK_STATE_ACTIVE,
// GTK_STATE_PRELIGHT,
// GTK_STATE_SELECTED,
// GTK_STATE_INSENSITIVE
//
static void gtk_widget_set_color(GtkWidget * widget,
GtkRcFlags flags,
GtkStateType state,
GdkColor * color);
/**
* Return the current keyboard modifier state.
*
* @return the current keyboard modifier state.
*
*/
static GdkModifierType gdk_keyboard_get_modifiers();
/**
* Flash an area within a GDK window (or the whole window)
*
* @param aGdkWindow The GDK window to flash.
* @param aTimes Number of times to flash the area.
* @param aInterval Interval between flashes in milliseconds.
* @param aArea The area to flash. The whole window if NULL.
*
*/
static void gdk_window_flash(GdkWindow * aGdkWindow,
unsigned int aTimes,
unsigned long aInterval,
GdkRectangle * aArea);
};
#endif // __nsGtkEventHandler.h

View File

@@ -0,0 +1,141 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsLabel.h"
#include "nsString.h"
NS_IMPL_ADDREF_INHERITED(nsLabel, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsLabel, nsWidget)
NS_IMPL_QUERY_INTERFACE2(nsLabel, nsILabel, nsIWidget)
//-------------------------------------------------------------------------
//
// nsLabel constructor
//
//-------------------------------------------------------------------------
nsLabel::nsLabel() : nsWidget(), nsILabel()
{
NS_INIT_REFCNT();
mAlignment = eAlign_Left;
}
//-------------------------------------------------------------------------
//
// nsLabel destructor
//
//-------------------------------------------------------------------------
nsLabel::~nsLabel()
{
}
//-------------------------------------------------------------------------
//
// Create the nativeLabel widget
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsLabel::CreateNative(GtkObject *parentWindow)
{
unsigned char alignment = GetNativeAlignment();
mWidget = gtk_label_new("");
gtk_widget_set_name(mWidget, "nsLabel");
gtk_misc_set_alignment(GTK_MISC(mWidget), 0.0, alignment);
return NS_OK;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsLabel::PreCreateWidget(nsWidgetInitData *aInitData)
{
if (nsnull != aInitData) {
nsLabelInitData* data = (nsLabelInitData *) aInitData;
mAlignment = data->mAlignment;
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set alignment
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsLabel::SetAlignment(nsLabelAlignment aAlignment)
{
GtkJustification align;
mAlignment = aAlignment;
align = GetNativeAlignment();
gtk_misc_set_alignment(GTK_MISC(mWidget), 0.0, align);
return NS_OK;
}
//-------------------------------------------------------------------------
//
//
//
//-------------------------------------------------------------------------
GtkJustification nsLabel::GetNativeAlignment()
{
switch (mAlignment) {
case eAlign_Right : return GTK_JUSTIFY_RIGHT;
case eAlign_Left : return GTK_JUSTIFY_LEFT;
case eAlign_Center: return GTK_JUSTIFY_CENTER;
default :
return GTK_JUSTIFY_LEFT;
}
return GTK_JUSTIFY_LEFT;
}
//-------------------------------------------------------------------------
//
// Set this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsLabel::SetLabel(const nsString& aText)
{
NS_ALLOC_STR_BUF(label, aText, 256);
gtk_label_set(GTK_LABEL(mWidget), label);
NS_FREE_STR_BUF(label);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsLabel::GetLabel(nsString& aBuffer)
{
char * text;
gtk_label_get(GTK_LABEL(mWidget), &text);
aBuffer.SetLength(0);
aBuffer.Append(text);
return NS_OK;
}

View File

@@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsLabel_h__
#define nsLabel_h__
#include "nsWidget.h"
#include "nsILabel.h"
/**
* Native GTK+ Label wrapper
*/
class nsLabel : public nsWidget,
public nsILabel
{
public:
nsLabel();
virtual ~nsLabel();
NS_DECL_ISUPPORTS_INHERITED
// nsILabel part
NS_IMETHOD SetLabel(const nsString &aText);
NS_IMETHOD GetLabel(nsString &aBuffer);
NS_IMETHOD SetAlignment(nsLabelAlignment aAlignment);
NS_IMETHOD PreCreateWidget(nsWidgetInitData *aInitData);
virtual PRBool OnMove(PRInt32 aX, PRInt32 aY) { return PR_FALSE; }
virtual PRBool OnResize(nsRect &aRect) { return PR_FALSE; }
protected:
NS_METHOD CreateNative(GtkObject *parentWindow);
GtkJustification GetNativeAlignment();
nsLabelAlignment mAlignment;
};
#endif // nsLabel_h__

View File

@@ -0,0 +1,394 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsListBox.h"
#include "nsString.h"
NS_IMPL_ADDREF_INHERITED(nsListBox, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsListBox, nsWidget)
NS_IMPL_QUERY_INTERFACE3(nsListBox, nsIListBox, nsIListWidget, nsIWidget)
//-------------------------------------------------------------------------
//
// nsListBox constructor
//
//-------------------------------------------------------------------------
nsListBox::nsListBox() : nsWidget(), nsIListWidget(), nsIListBox()
{
NS_INIT_REFCNT();
mMultiSelect = PR_FALSE;
mCList = nsnull;
}
//-------------------------------------------------------------------------
//
// nsListBox:: destructor
//
//-------------------------------------------------------------------------
nsListBox::~nsListBox()
{
}
void nsListBox::InitCallbacks(char * aName)
{
InstallButtonPressSignal(mCList);
InstallButtonReleaseSignal(mCList);
InstallEnterNotifySignal(mCList);
InstallLeaveNotifySignal(mCList);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mCList,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_EXPOSURE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
}
//-------------------------------------------------------------------------
//
// initializer
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::SetMultipleSelection(PRBool aMultipleSelections)
{
mMultiSelect = aMultipleSelections;
if (mCList) {
if (mMultiSelect)
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_MULTIPLE);
else
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// AddItemAt
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
{
if (mCList) {
gchar *text[2];
const nsAutoCString tempStr(aItem);
text[0] = (gchar*)(const char *)tempStr;
text[1] = (gchar*)NULL;
gtk_clist_insert(GTK_CLIST(mCList), (int)aPosition, text);
// XXX Im not sure using the string address is the right thing to
// store in the row data.
gtk_clist_set_row_data(GTK_CLIST(mCList), aPosition, (gpointer)&aItem);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Finds an item at a postion
//
//-------------------------------------------------------------------------
PRInt32 nsListBox::FindItem(nsString &aItem, PRInt32 aStartPos)
{
int i = -1;
if (mCList) {
i = gtk_clist_find_row_from_data(GTK_CLIST(mCList), (gpointer)&aItem);
if (i < aStartPos) {
i = -1;
}
}
return i;
}
//-------------------------------------------------------------------------
//
// CountItems - Get Item Count
//
//-------------------------------------------------------------------------
PRInt32 nsListBox::GetItemCount()
{
if (mCList) {
return GTK_CLIST(mCList)->rows;
}
else {
return 0;
}
}
//-------------------------------------------------------------------------
//
// Removes an Item at a specified location
//
//-------------------------------------------------------------------------
PRBool nsListBox::RemoveItemAt(PRInt32 aPosition)
{
if (mCList) {
gtk_clist_remove(GTK_CLIST(mCList), aPosition);
}
return PR_TRUE;
}
//-------------------------------------------------------------------------
//
//
//
//-------------------------------------------------------------------------
PRBool nsListBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
{
PRBool result = PR_FALSE;
anItem.Truncate();
if (mCList) {
char *text = nsnull;
gtk_clist_get_text(GTK_CLIST(mCList),aPosition,0,&text);
if (text) {
anItem.Append(text);
result = PR_TRUE;
}
}
return result;
}
//-------------------------------------------------------------------------
//
// Gets the selected of selected item
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::GetSelectedItem(nsString& aItem)
{
aItem.Truncate();
if (mCList) {
PRInt32 i=0, idx=-1;
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && idx == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
char *text = nsnull;
gtk_clist_get_text(GTK_CLIST(mCList),i,0,&text);
if (text) {
aItem.Append(text);
}
return NS_OK;
}
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Gets the list of selected otems
//
//-------------------------------------------------------------------------
PRInt32 nsListBox::GetSelectedIndex()
{
PRInt32 i=0, idx=-1;
if (mCList) {
if (!mMultiSelect) {
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && idx == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
idx = i;
}
}
} else {
NS_ASSERTION(PR_FALSE, "Multi selection list box does not support GetSelectedIndex()");
}
}
return idx;
}
//-------------------------------------------------------------------------
//
// SelectItem
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::SelectItem(PRInt32 aPosition)
{
if (mCList) {
gtk_clist_select_row(GTK_CLIST(mCList), aPosition, 0);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// GetSelectedCount
//
//-------------------------------------------------------------------------
PRInt32 nsListBox::GetSelectedCount()
{
if (mCList) {
if (!GTK_CLIST(mCList)->selection)
return 0;
else
return (PRInt32)g_list_length(GTK_CLIST(mCList)->selection);
}
else {
return 0;
}
}
//-------------------------------------------------------------------------
//
// GetSelectedIndices
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
{
if (mCList) {
PRInt32 i=0, num = 0;
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && num < aSize; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
aIndices[num] = i;
num++;
}
}
}
else {
PRInt32 i = 0;
for (i = 0; i < aSize; i++) aIndices[i] = 0;
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// SetSelectedIndices
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::SetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
{
if (mCList) {
gtk_clist_unselect_all(GTK_CLIST(mCList));
int i;
for (i=0;i<aSize;i++) {
SelectItem(aIndices[i]);
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Deselect
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::Deselect()
{
if (mCList) {
gtk_clist_unselect_all(GTK_CLIST(mCList));
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set initial parameters
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::PreCreateWidget(nsWidgetInitData *aInitData)
{
if (nsnull != aInitData) {
nsListBoxInitData* data = (nsListBoxInitData *) aInitData;
mMultiSelect = data->mMultiSelect;
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Create the native widget
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsListBox::CreateNative(GtkObject *parentWindow)
{
// to handle scrolling
mWidget = gtk_scrolled_window_new (nsnull, nsnull);
gtk_widget_set_name(mWidget, "nsListBox");
gtk_container_set_border_width(GTK_CONTAINER(mWidget), 0);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (mWidget),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
mCList = ::gtk_clist_new(1);
gtk_clist_column_titles_hide(GTK_CLIST(mCList));
// Default (it may be changed)
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE);
SetMultipleSelection(mMultiSelect);
gtk_widget_show(mCList);
gtk_signal_connect(GTK_OBJECT(mCList),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
gtk_container_add (GTK_CONTAINER (mWidget), mCList);
return NS_OK;
}
void
nsListBox::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCList) {
mCList = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//-------------------------------------------------------------------------
//
// set font for listbox
//
//-------------------------------------------------------------------------
/*virtual*/
void nsListBox::SetFontNative(GdkFont *aFont)
{
GtkStyle *style = gtk_style_copy(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0))->style);
// gtk_style_copy ups the ref count of the font
gdk_font_unref (style->font);
style->font = aFont;
gdk_font_ref(style->font);
gtk_widget_set_style(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0)), style);
gtk_style_unref(style);
}

View File

@@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsListBox_h__
#define nsListBox_h__
#include "nsWidget.h"
#include "nsIListBox.h"
/**
* Native GTK+ Listbox wrapper
*/
class nsListBox : public nsWidget,
public nsIListWidget,
public nsIListBox
{
public:
nsListBox();
virtual ~nsListBox();
NS_DECL_ISUPPORTS_INHERITED
// nsIListBox interface
NS_IMETHOD PreCreateWidget(nsWidgetInitData *aInitData);
NS_IMETHOD SetMultipleSelection(PRBool aMultipleSelections);
NS_IMETHOD AddItemAt(nsString &aItem, PRInt32 aPosition);
PRInt32 FindItem(nsString &aItem, PRInt32 aStartPos);
PRInt32 GetItemCount();
PRBool RemoveItemAt(PRInt32 aPosition);
PRBool GetItemAt(nsString& anItem, PRInt32 aPosition);
NS_IMETHOD GetSelectedItem(nsString& aItem);
PRInt32 GetSelectedIndex();
PRInt32 GetSelectedCount();
NS_IMETHOD GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize);
NS_IMETHOD SetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize);
NS_IMETHOD SelectItem(PRInt32 aPosition);
NS_IMETHOD Deselect() ;
virtual void SetFontNative(GdkFont *aFont);
protected:
NS_IMETHOD CreateNative(GtkObject *parentWindow);
virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mCList;
PRBool mMultiSelect;
};
#endif // nsListBox_h__

View File

@@ -0,0 +1,316 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsLookAndFeel.h"
#include <gtk/gtkinvisible.h>
#define GDK_COLOR_TO_NS_RGB(c) \
((nscolor) NS_RGB(c.red, c.green, c.blue))
NS_IMPL_ISUPPORTS1(nsLookAndFeel, nsILookAndFeel)
//-------------------------------------------------------------------------
//
// Query interface implementation
//
//-------------------------------------------------------------------------
nsLookAndFeel::nsLookAndFeel()
{
NS_INIT_REFCNT();
mWidget = gtk_invisible_new();
gtk_widget_ensure_style(mWidget);
mStyle = gtk_widget_get_style(mWidget);
}
nsLookAndFeel::~nsLookAndFeel()
{
gtk_widget_destroy(mWidget);
}
NS_IMETHODIMP nsLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor)
{
nsresult res = NS_OK;
aColor = 0; // default color black
switch (aID) {
case eColor_WindowBackground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_WindowForeground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
case eColor_WidgetBackground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_WidgetForeground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
case eColor_WidgetSelectBackground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
break;
case eColor_WidgetSelectForeground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_SELECTED]);
break;
case eColor_Widget3DHighlight:
aColor = NS_RGB(0xa0,0xa0,0xa0);
break;
case eColor_Widget3DShadow:
aColor = NS_RGB(0x40,0x40,0x40);
break;
case eColor_TextBackground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_TextForeground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
case eColor_TextSelectBackground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
break;
case eColor_TextSelectForeground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]);
break;
// css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
case eColor_activeborder:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_activecaption:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_appworkspace:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_background:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_captiontext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
case eColor_graytext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
break;
case eColor_highlight:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
break;
case eColor_highlighttext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_SELECTED]);
break;
case eColor_inactiveborder:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_inactivecaption:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_INSENSITIVE]);
break;
case eColor_inactivecaptiontext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
break;
case eColor_infobackground:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_infotext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
case eColor_menu:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_menutext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
case eColor_scrollbar:
break;
case eColor_threedface:
case eColor_buttonface:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_buttonhighlight: // ?
case eColor_threedhighlight:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_ACTIVE]);
break;
case eColor_buttontext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
case eColor_buttonshadow:
case eColor_threeddarkshadow:
case eColor_threedshadow: // i think these should be the same
aColor = NS_DarkenColor(NS_DarkenColor(NS_DarkenColor(NS_DarkenColor(NS_DarkenColor(GDK_COLOR_TO_NS_RGB(mStyle->light[GTK_STATE_NORMAL]))))));
// aColor = GDK_COLOR_TO_NS_RGB(mStyle->dark[GTK_STATE_NORMAL]); // dark style gives me bright green?!
break;
case eColor_threedlightshadow:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->light[GTK_STATE_NORMAL]);
break;
case eColor_window:
case eColor_windowframe:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
break;
case eColor_windowtext:
aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
break;
default:
/* default color is BLACK */
aColor = 0;
res = NS_ERROR_FAILURE;
break;
}
// printf("%i, %i, %i\n", NS_GET_R(aColor), NS_GET_B(aColor), NS_GET_G(aColor));
return res;
}
NS_IMETHODIMP nsLookAndFeel::GetMetric(const nsMetricID aID, PRInt32 & aMetric)
{
nsresult res = NS_OK;
switch (aID) {
case eMetric_WindowTitleHeight:
aMetric = 0;
break;
case eMetric_WindowBorderWidth:
// aMetric = mStyle->klass->xthickness;
break;
case eMetric_WindowBorderHeight:
// aMetric = mStyle->klass->ythickness;
break;
case eMetric_Widget3DBorder:
// aMetric = 4;
break;
case eMetric_TextFieldHeight:
{
GtkRequisition req;
GtkWidget *text = gtk_entry_new();
// needed to avoid memory leak
gtk_widget_ref(text);
gtk_object_sink(GTK_OBJECT(text));
gtk_widget_size_request(text,&req);
aMetric = req.height;
gtk_widget_destroy(text);
gtk_widget_unref(text);
}
break;
case eMetric_TextFieldBorder:
aMetric = 2;
break;
case eMetric_TextVerticalInsidePadding:
aMetric = 0;
break;
case eMetric_TextShouldUseVerticalInsidePadding:
aMetric = 0;
break;
case eMetric_TextHorizontalInsideMinimumPadding:
aMetric = 15;
break;
case eMetric_TextShouldUseHorizontalInsideMinimumPadding:
aMetric = 1;
break;
case eMetric_ButtonHorizontalInsidePaddingNavQuirks:
aMetric = 10;
break;
case eMetric_ButtonHorizontalInsidePaddingOffsetNavQuirks:
aMetric = 8;
break;
case eMetric_CheckboxSize:
aMetric = 15;
break;
case eMetric_RadioboxSize:
aMetric = 15;
break;
case eMetric_ListShouldUseHorizontalInsideMinimumPadding:
aMetric = 15;
break;
case eMetric_ListHorizontalInsideMinimumPadding:
aMetric = 15;
break;
case eMetric_ListShouldUseVerticalInsidePadding:
aMetric = 1;
break;
case eMetric_ListVerticalInsidePadding:
aMetric = 1;
break;
case eMetric_CaretBlinkTime:
aMetric = 500;
break;
case eMetric_CaretWidthTwips:
aMetric = 20;
break;
default:
aMetric = 0;
res = NS_ERROR_FAILURE;
}
return res;
}
NS_IMETHODIMP nsLookAndFeel::GetMetric(const nsMetricFloatID aID, float & aMetric)
{
nsresult res = NS_OK;
switch (aID) {
case eMetricFloat_TextFieldVerticalInsidePadding:
aMetric = 0.25f;
break;
case eMetricFloat_TextFieldHorizontalInsidePadding:
aMetric = 0.95f; // large number on purpose so minimum padding is used
break;
case eMetricFloat_TextAreaVerticalInsidePadding:
aMetric = 0.40f;
break;
case eMetricFloat_TextAreaHorizontalInsidePadding:
aMetric = 0.40f; // large number on purpose so minimum padding is used
break;
case eMetricFloat_ListVerticalInsidePadding:
aMetric = 0.10f;
break;
case eMetricFloat_ListHorizontalInsidePadding:
aMetric = 0.40f;
break;
case eMetricFloat_ButtonVerticalInsidePadding:
aMetric = 0.25f;
break;
case eMetricFloat_ButtonHorizontalInsidePadding:
aMetric = 0.25f;
break;
default:
aMetric = -1.0;
res = NS_ERROR_FAILURE;
}
return res;
}
#ifdef NS_DEBUG
NS_IMETHODIMP nsLookAndFeel::GetNavSize(const nsMetricNavWidgetID aWidgetID,
const nsMetricNavFontID aFontID,
const PRInt32 aFontSize,
nsSize &aSize)
{
aSize.width = 0;
aSize.height = 0;
return NS_ERROR_NOT_IMPLEMENTED;
}
#endif

View File

@@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsLookAndFeel
#define __nsLookAndFeel
#include "nsILookAndFeel.h"
#include <gtk/gtk.h>
class nsLookAndFeel: public nsILookAndFeel {
NS_DECL_ISUPPORTS
public:
nsLookAndFeel();
virtual ~nsLookAndFeel();
NS_IMETHOD GetColor(const nsColorID aID, nscolor &aColor);
NS_IMETHOD GetMetric(const nsMetricID aID, PRInt32 & aMetric);
NS_IMETHOD GetMetric(const nsMetricFloatID aID, float & aMetric);
#ifdef NS_DEBUG
// This method returns the actual (or nearest estimate)
// of the Navigator size for a given form control for a given font
// and font size. This is used in NavQuirks mode to see how closely
// we match its size
NS_IMETHOD GetNavSize(const nsMetricNavWidgetID aWidgetID,
const nsMetricNavFontID aFontID,
const PRInt32 aFontSize,
nsSize &aSize);
#endif
protected:
GtkStyle *mStyle;
GtkWidget *mWidget;
};
#endif

View File

@@ -0,0 +1,792 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsMenu.h"
#include "nsIComponentManager.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsIMenuBar.h"
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsString.h"
#include "nsGtkEventHandler.h"
#include "nsCOMPtr.h"
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
nsresult nsMenu::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(nsIMenu::GetIID())) {
*aInstancePtr = (void*)(nsIMenu*) this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIMenu*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIMenuListener::GetIID())) {
*aInstancePtr = (void*)(nsIMenuListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsMenu)
NS_IMPL_RELEASE(nsMenu)
//-------------------------------------------------------------------------
//
// nsMenu constructor
//
//-------------------------------------------------------------------------
nsMenu::nsMenu() : nsIMenu()
{
NS_INIT_REFCNT();
mNumMenuItems = 0;
mMenu = nsnull;
mMenuParent = nsnull;
mMenuBarParent = nsnull;
mListener = nsnull;
mConstructCalled = PR_FALSE;
mDOMNode = nsnull;
mWebShell = nsnull;
mDOMElement = nsnull;
mAccessKey = "_";
}
//-------------------------------------------------------------------------
//
// nsMenu destructor
//
//-------------------------------------------------------------------------
nsMenu::~nsMenu()
{
//g_print("nsMenu::~nsMenu() called\n");
NS_IF_RELEASE(mListener);
// Free our menu items
RemoveAll();
gtk_widget_destroy(mMenu);
mMenu = nsnull;
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//-------------------------------------------------------------------------
NS_METHOD nsMenu::Create(nsISupports *aParent, const nsString &aLabel)
{
if(aParent)
{
nsIMenuBar * menubar = nsnull;
aParent->QueryInterface(nsIMenuBar::GetIID(), (void**) &menubar);
if(menubar)
{
mMenuBarParent = menubar;
NS_RELEASE(menubar);
}
else
{
nsIMenu * menu = nsnull;
aParent->QueryInterface(nsIMenu::GetIID(), (void**) &menu);
if(menu)
{
mMenuParent = menu;
NS_RELEASE(menu);
}
}
}
mLabel = aLabel;
mMenu = gtk_menu_new();
gtk_signal_connect (GTK_OBJECT (mMenu), "map",
GTK_SIGNAL_FUNC(menu_map_handler),
this);
gtk_signal_connect (GTK_OBJECT (mMenu), "unmap",
GTK_SIGNAL_FUNC(menu_unmap_handler),
this);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::GetParent(nsISupports*& aParent)
{
aParent = nsnull;
if (nsnull != mMenuParent) {
return mMenuParent->QueryInterface(kISupportsIID,
(void**)&aParent);
} else if (nsnull != mMenuBarParent) {
return mMenuBarParent->QueryInterface(kISupportsIID,
(void**)&aParent);
}
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::GetLabel(nsString &aText)
{
aText = mLabel;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::SetLabel(const nsString &aText)
{
/* we Do GetLabel() when we are adding the menu...
* but we might want to redo this.
*/
mLabel = aText;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::GetAccessKey(nsString &aText)
{
aText = mAccessKey;
char *foo = mAccessKey.ToNewCString();
#ifdef DEBUG_pavlov
g_print("GetAccessKey returns \"%s\"\n", foo);
#endif
nsCRT::free(foo);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::SetAccessKey(const nsString &aText)
{
mAccessKey = aText;
char *foo = mAccessKey.ToNewCString();
#ifdef DEBUG_pavlov
g_print("SetAccessKey setting to \"%s\"\n", foo);
#endif
nsCRT::free(foo);
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Set enabled state
*
*/
NS_METHOD nsMenu::SetEnabled(PRBool aIsEnabled)
{
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Get enabled state
*
*/
NS_METHOD nsMenu::GetEnabled(PRBool* aIsEnabled)
{
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Query if this is the help menu
*
*/
NS_METHOD nsMenu::IsHelpMenu(PRBool* aIsHelpMenu)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::AddItem(nsISupports * aItem)
{
if(aItem)
{
nsIMenuItem * menuitem = nsnull;
aItem->QueryInterface(nsIMenuItem::GetIID(),
(void**)&menuitem);
if(menuitem)
{
AddMenuItem(menuitem); // nsMenu now owns this
NS_RELEASE(menuitem);
}
else
{
nsIMenu * menu = nsnull;
aItem->QueryInterface(nsIMenu::GetIID(),
(void**)&menu);
if(menu)
{
AddMenu(menu); // nsMenu now owns this
NS_RELEASE(menu);
}
}
}
return NS_OK;
}
// local method used by nsMenu::AddItem
//-------------------------------------------------------------------------
NS_METHOD nsMenu::AddMenuItem(nsIMenuItem * aMenuItem)
{
GtkWidget *widget;
void *voidData;
aMenuItem->GetNativeData(voidData);
widget = GTK_WIDGET(voidData);
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
// XXX add aMenuItem to internal data structor list
// Need to be adding an nsISupports *, not nsIMenuItem *
nsISupports * supports = nsnull;
aMenuItem->QueryInterface(kISupportsIID,
(void**)&supports);
{
mMenuItemVoidArray.AppendElement(supports);
mNumMenuItems++;
}
return NS_OK;
}
// local method used by nsMenu::AddItem
//-------------------------------------------------------------------------
NS_METHOD nsMenu::AddMenu(nsIMenu * aMenu)
{
nsString Label;
GtkWidget *newmenu=nsnull;
void *voidData=NULL;
aMenu->GetLabel(Label);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID,
nsnull,
nsIMenuItem::GetIID(),
(void**)&pnsMenuItem);
if (NS_OK == rv) {
nsISupports * supports = nsnull;
QueryInterface(kISupportsIID, (void**) &supports);
pnsMenuItem->Create(supports, Label, PR_FALSE); //PR_TRUE);
NS_RELEASE(supports);
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
void * menuitem = nsnull;
pnsMenuItem->GetNativeData(menuitem);
voidData = NULL;
aMenu->GetNativeData(&voidData);
newmenu = GTK_WIDGET(voidData);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), newmenu);
NS_RELEASE(pnsMenuItem);
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::AddSeparator()
{
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(
kMenuItemCID, nsnull, nsIMenuItem::GetIID(), (void**)&pnsMenuItem);
if (NS_OK == rv) {
nsString tmp = "menuseparator";
nsISupports * supports = nsnull;
QueryInterface(kISupportsIID, (void**) &supports);
pnsMenuItem->Create(supports, tmp, PR_TRUE);
NS_RELEASE(supports);
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
NS_RELEASE(pnsMenuItem);
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::GetItemCount(PRUint32 &aCount)
{
// this should be right.. does it need to be +1 ?
aCount = g_list_length(GTK_MENU_SHELL(mMenu)->children);
//g_print("nsMenu::GetItemCount = %i\n", aCount);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::GetItemAt(const PRUint32 aPos,
nsISupports *&aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::InsertItemAt(const PRUint32 aPos,
nsISupports *aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::RemoveItem(const PRUint32 aPos)
{
#if 0
// this may work here better than Removeall(), but i'm not sure how to test this one
nsISupports *item = mMenuItemVoidArray[aPos];
delete item;
mMenuItemVoidArray.RemoveElementAt(aPos);
#endif
/*
gtk_menu_shell_remove (GTK_MENU_SHELL (mMenu), item);
nsCRT::free(labelStr);
voidData = NULL;
aMenu->GetNativeData(&voidData);
newmenu = GTK_WIDGET(voidData);
gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
*/
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::RemoveAll()
{
//g_print("nsMenu::RemoveAll()\n");
#if 0
// this doesn't work quite right, but this is about all that should really be needed
int i=0;
nsIMenu *menu = nsnull;
nsIMenuItem *menuitem = nsnull;
nsISupports *item = nsnull;
for (i=mMenuItemVoidArray.Count(); i>0; i--)
{
item = (nsISupports*)mMenuItemVoidArray[i-1];
if(nsnull != item)
{
if (NS_OK == item->QueryInterface(nsIMenuItem::GetIID(), (void**)&menuitem)) {
// we do this twice because we have to do it once for QueryInterface,
// then we want to get rid of it.
// g_print("remove nsMenuItem\n");
NS_RELEASE(menuitem);
NS_RELEASE(item);
menuitem = nsnull;
} else if (NS_OK == item->QueryInterface(nsIMenu::GetIID(), (void**)&menu)) {
// g_print("remove nsMenu\n");
NS_RELEASE(menu);
NS_RELEASE(item);
menu = nsnull;
}
// mMenuItemVoidArray.RemoveElementAt(i-1);
}
}
mMenuItemVoidArray.Clear();
#else
for (int i = mMenuItemVoidArray.Count(); i > 0; i--) {
if(nsnull != mMenuItemVoidArray[i-1]) {
nsIMenuItem * menuitem = nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(nsIMenuItem::GetIID(),
(void**)&menuitem);
if(menuitem) {
void *gtkmenuitem = nsnull;
menuitem->GetNativeData(gtkmenuitem);
if (gtkmenuitem) {
// gtk_widget_ref(GTK_WIDGET(gtkmenuitem));
//gtk_widget_destroy(GTK_WIDGET(gtkmenuitem));
gtk_container_remove (GTK_CONTAINER (mMenu), GTK_WIDGET(gtkmenuitem));
}
} else {
nsIMenu * menu= nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(nsIMenu::GetIID(),
(void**)&menu);
if(menu)
{
void * gtkmenu = nsnull;
menu->GetNativeData(&gtkmenu);
if(gtkmenu){
//g_print("gtkmenu removed");
//gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
}
}
}
}
}
#endif
//g_print("end RemoveAll\n");
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::GetNativeData(void ** aData)
{
*aData = (void *)mMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::SetNativeData(void * aData)
{
return NS_OK;
}
GtkWidget *nsMenu::GetNativeParent()
{
void * voidData;
if (nsnull != mMenuParent) {
mMenuParent->GetNativeData(&voidData);
} else if (nsnull != mMenuBarParent) {
mMenuBarParent->GetNativeData(voidData);
} else {
return nsnull;
}
return GTK_WIDGET(voidData);
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::AddMenuListener(nsIMenuListener * aMenuListener)
{
mListener = aMenuListener;
NS_ADDREF(mListener);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenu::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (aMenuListener == mListener) {
NS_IF_RELEASE(mListener);
}
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsMenu::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
if (nsnull != mListener) {
mListener->MenuSelected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
nsEventStatus nsMenu::MenuSelected(const nsMenuEvent & aMenuEvent)
{
if (nsnull != mListener) {
mListener->MenuSelected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenu::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
if (nsnull != mListener) {
mListener->MenuDeselected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenu::MenuConstruct(const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aWebShell)
{
//g_print("nsMenu::MenuConstruct called \n");
if(menuNode){
SetDOMNode((nsIDOMNode*)menuNode);
}
if(!aWebShell){
aWebShell = mWebShell;
}
// First open the menu.
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if (domElement)
domElement->SetAttribute("open", "true");
/// Now get the kids. Retrieve our menupopup child.
nsCOMPtr<nsIDOMNode> menuPopupNode;
mDOMNode->GetFirstChild(getter_AddRefs(menuPopupNode));
while (menuPopupNode) {
nsCOMPtr<nsIDOMElement> menuPopupElement(do_QueryInterface(menuPopupNode));
if (menuPopupElement) {
nsString menuPopupNodeType;
menuPopupElement->GetNodeName(menuPopupNodeType);
if (menuPopupNodeType.Equals("menupopup"))
break;
}
nsCOMPtr<nsIDOMNode> oldMenuPopupNode(menuPopupNode);
oldMenuPopupNode->GetNextSibling(getter_AddRefs(menuPopupNode));
}
if (!menuPopupNode)
return nsEventStatus_eIgnore;
nsCOMPtr<nsIDOMNode> menuitemNode;
menuPopupNode->GetFirstChild(getter_AddRefs(menuitemNode));
unsigned short menuIndex = 0;
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
nsString menuitemName;
menuitemElement->GetNodeName(menuitemNodeType);
if (menuitemNodeType.Equals("menuitem")) {
// LoadMenuItem
LoadMenuItem(this,
menuitemElement,
menuitemNode,
menuIndex,
(nsIWebShell*)aWebShell);
} else if (menuitemNodeType.Equals("menuseparator")) {
AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Load a submenu
LoadSubMenu(this, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenu::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
// Close the node.
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if (domElement)
domElement->RemoveAttribute("open");
//g_print("nsMenu::MenuDestruct called \n");
mConstructCalled = PR_FALSE;
RemoveAll();
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
/**
* Set DOMNode
*
*/
NS_METHOD nsMenu::SetDOMNode(nsIDOMNode * aMenuNode)
{
mDOMNode = aMenuNode;
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Set DOMElement
*
*/
NS_METHOD nsMenu::SetDOMElement(nsIDOMElement * aMenuElement)
{
mDOMElement = aMenuElement;
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Set WebShell
*
*/
NS_METHOD nsMenu::SetWebShell(nsIWebShell * aWebShell)
{
mWebShell = aWebShell;
return NS_OK;
}
//----------------------------------------
void nsMenu::LoadMenuItem(nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell)
{
static const char* NS_STRING_TRUE = "true";
nsString disabled;
nsString menuitemName;
nsString menuitemCmd;
menuitemElement->GetAttribute(nsAutoString("disabled"), disabled);
menuitemElement->GetAttribute(nsAutoString("value"), menuitemName);
menuitemElement->GetAttribute(nsAutoString("cmd"), menuitemCmd);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID,
nsnull,
nsIMenuItem::GetIID(),
(void**)&pnsMenuItem);
if (NS_OK == rv) {
pnsMenuItem->Create(pParentMenu, menuitemName, PR_FALSE);
nsISupports * supports = nsnull;
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
pParentMenu->AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
if(disabled == NS_STRING_TRUE ) {
pnsMenuItem->SetEnabled(PR_FALSE);
}
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
//return NS_ERROR_FAILURE;
return;
}
nsAutoString cmdAtom("oncommand");
nsString cmdName;
domElement->GetAttribute(cmdAtom, cmdName);
pnsMenuItem->SetCommand(cmdName);
// DO NOT use passed in webshell because of messed up windows dynamic loading
// code.
pnsMenuItem->SetWebShell(mWebShell);
pnsMenuItem->SetDOMElement(domElement);
NS_RELEASE(pnsMenuItem);
}
return;
}
//----------------------------------------
void nsMenu::LoadSubMenu(nsIMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode)
{
nsString menuName;
menuElement->GetAttribute(nsAutoString("value"), menuName);
//printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID,
nsnull,
nsIMenu::GetIID(),
(void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pParentMenu->QueryInterface(kISupportsIID, (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports); // Balance QI
// Set nsMenu Name
pnsMenu->SetLabel(menuName);
supports = nsnull;
pnsMenu->QueryInterface(kISupportsIID, (void**) &supports);
pParentMenu->AddItem(supports); // parent takes ownership
NS_RELEASE(supports);
pnsMenu->SetWebShell(mWebShell);
pnsMenu->SetDOMNode(menuNode);
/*
// Begin menuitem inner loop
unsigned short menuIndex = 0;
nsCOMPtr<nsIDOMNode> menuitemNode;
menuNode->GetFirstChild(getter_AddRefs(menuitemNode));
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
menuitemElement->GetNodeName(menuitemNodeType);
#ifdef DEBUG_saari
printf("Type [%s] %d\n", menuitemNodeType.ToNewCString(), menuitemNodeType.Equals("menuseparator"));
#endif
if (menuitemNodeType.Equals("menuitem")) {
// Load a menuitem
LoadMenuItem(pnsMenu, menuitemElement, menuitemNode, menuIndex, mWebShell);
} else if (menuitemNodeType.Equals("menuseparator")) {
pnsMenu->AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Add a submenu
LoadSubMenu(pnsMenu, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
*/
}
}

View File

@@ -0,0 +1,120 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsMenu_h__
#define nsMenu_h__
#include "nsIMenu.h"
#include "nsIMenuListener.h"
#include "nsVoidArray.h"
class nsIDOMElement;
class nsIDOMNode;
class nsIMenuBar;
class nsIWebShell;
/**
* Native GTK+ Menu wrapper
*/
class nsMenu : public nsIMenu, public nsIMenuListener
{
public:
nsMenu();
virtual ~nsMenu();
NS_DECL_ISUPPORTS
// nsIMenuListener methods
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
NS_IMETHOD Create(nsISupports * aParent, const nsString &aLabel);
// nsIMenu Methods
NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetLabel(const nsString &aText);
NS_IMETHOD GetAccessKey(nsString &aText);
NS_IMETHOD SetAccessKey(const nsString &aText);
NS_IMETHOD AddItem(nsISupports * aItem);
NS_IMETHOD AddMenuItem(nsIMenuItem * aMenuItem);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
NS_IMETHOD AddSeparator();
NS_IMETHOD GetItemCount(PRUint32 &aCount);
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem);
NS_IMETHOD RemoveItem(const PRUint32 aPos);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void** aData);
NS_IMETHOD SetNativeData(void* aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD SetEnabled(PRBool aIsEnabled);
NS_IMETHOD GetEnabled(PRBool* aIsEnabled);
NS_IMETHOD IsHelpMenu(PRBool* aIsHelp);
NS_IMETHOD SetDOMNode(nsIDOMNode * aMenuNode);
NS_IMETHOD SetDOMElement(nsIDOMElement * aMenuElement);
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell);
protected:
void LoadMenuItem(
nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(
nsIMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
GtkWidget *GetNativeParent();
nsString mLabel;
nsString mAccessKey;
PRUint32 mNumMenuItems;
GtkWidget *mMenu;
nsVoidArray mMenuItemVoidArray;
nsIMenu *mMenuParent;
nsIMenuBar *mMenuBarParent;
nsIMenuListener * mListener;
PRBool mConstructCalled;
nsIDOMNode * mDOMNode;
nsIWebShell * mWebShell;
nsIDOMElement * mDOMElement;
};
#endif // nsMenu_h__

View File

@@ -0,0 +1,354 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsMenuBar.h"
#include "nsMenuItem.h"
#include "nsIComponentManager.h"
#include "nsIDOMNode.h"
#include "nsIMenu.h"
#include "nsIWebShell.h"
#include "nsIWidget.h"
#include "nsString.h"
#include "nsGtkEventHandler.h"
#include "nsCOMPtr.h"
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuBarCID, NS_MENUBAR_CID);
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
nsresult nsMenuBar::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(nsIMenuBar::GetIID())) {
*aInstancePtr = (void*) ((nsIMenuBar*) this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) ((nsISupports*)(nsIMenuBar*) this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIMenuListener::GetIID())) {
*aInstancePtr = (void*) ((nsIMenuListener*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsMenuBar)
NS_IMPL_RELEASE(nsMenuBar)
//-------------------------------------------------------------------------
//
// nsMenuBar constructor
//
//-------------------------------------------------------------------------
nsMenuBar::nsMenuBar() : nsIMenuBar(), nsIMenuListener()
{
NS_INIT_REFCNT();
mNumMenus = 0;
mMenuBar = nsnull;
mParent = nsnull;
mIsMenuBarAdded = PR_FALSE;
mWebShell = nsnull;
mDOMNode = nsnull;
}
//-------------------------------------------------------------------------
//
// nsMenuBar destructor
//
//-------------------------------------------------------------------------
nsMenuBar::~nsMenuBar()
{
// Release the menus
RemoveAll();
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::Create(nsIWidget *aParent)
{
SetParent(aParent);
mMenuBar = gtk_menu_bar_new();
gtk_widget_show(mMenuBar);
mParent->SetMenuBar(this);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetParent(nsIWidget *&aParent)
{
aParent = mParent;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::SetParent(nsIWidget *aParent)
{
mParent = aParent;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::AddMenu(nsIMenu * aMenu)
{
nsString Label;
GtkWidget *widget, *nmenu;
void *voidData;
nsISupports * supports = nsnull;
aMenu->QueryInterface(kISupportsIID, (void**)&supports);
if (supports) {
mMenusVoidArray.AppendElement(aMenu);
mNumMenus++;
}
aMenu->GetLabel(Label);
// get access key
nsString accessKey = " ";
aMenu->GetAccessKey(accessKey);
if(accessKey != " ")
{
// munge acess key into name
PRInt32 offset = Label.Find(accessKey);
if(offset != -1)
Label.Insert("_", offset);
}
char *foo = Label.ToNewCString();
g_print("%s\n", foo);
nsCRT::free(foo);
widget = nsMenuItem::CreateLocalized(Label);
gtk_widget_show(widget);
gtk_menu_bar_append (GTK_MENU_BAR (mMenuBar), widget);
aMenu->GetNativeData(&voidData);
nmenu = GTK_WIDGET(voidData);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), nmenu);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetMenuCount(PRUint32 &aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::RemoveMenu(const PRUint32 aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::RemoveAll()
{
for (int i = mMenusVoidArray.Count(); i > 0; i--) {
if(nsnull != mMenusVoidArray[i-1]) {
nsIMenu * menu = nsnull;
((nsISupports*)mMenusVoidArray[i-1])->QueryInterface(nsIMenu::GetIID(), (void**)&menu);
if(menu) {
//void * gtkmenu= nsnull;
//menu->GetNativeData(&gtkmenu);
//if(gtkmenu){
// gtk_container_remove (GTK_CONTAINER (mMenuBar), GTK_WIDGET(gtkmenu) );
//}
NS_RELEASE(menu);
g_print("menu release \n");
int num =((nsISupports*)mMenusVoidArray[i-1])->Release();
while(num) {
g_print("menu release again!\n");
num = ((nsISupports*)mMenusVoidArray[i-1])->Release();
}
}
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetNativeData(void *& aData)
{
aData = (void *)mMenuBar;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::SetNativeData(void * aData)
{
// Temporary hack for MacOS. Will go away when nsMenuBar handles it's own
// construction
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::Paint()
{
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsMenuListener interface
//
//-------------------------------------------------------------------------
nsEventStatus nsMenuBar::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
nsEventStatus nsMenuBar::MenuSelected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
nsEventStatus nsMenuBar::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
nsEventStatus nsMenuBar::MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menubarNode,
void * aWebShell)
{
mWebShell = (nsIWebShell*) aWebShell;
mDOMNode = (nsIDOMNode*)menubarNode;
nsIMenuBar * pnsMenuBar = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuBarCID,
nsnull,
nsIMenuBar::GetIID(),
(void**)&pnsMenuBar);
if (NS_OK == rv) {
if (nsnull != pnsMenuBar) {
pnsMenuBar->Create(aParentWindow);
// set pnsMenuBar as a nsMenuListener on aParentWindow
nsCOMPtr<nsIMenuListener> menuListener;
pnsMenuBar->QueryInterface(nsIMenuListener::GetIID(), getter_AddRefs(menuListener));
aParentWindow->AddMenuListener(menuListener);
nsCOMPtr<nsIDOMNode> menuNode;
((nsIDOMNode*)menubarNode)->GetFirstChild(getter_AddRefs(menuNode));
while (menuNode) {
nsCOMPtr<nsIDOMElement> menuElement(do_QueryInterface(menuNode));
if (menuElement) {
nsString menuNodeType;
nsString menuName;
nsString menuAccessKey = " ";
menuElement->GetNodeName(menuNodeType);
if (menuNodeType.Equals("menu")) {
menuElement->GetAttribute(nsAutoString("value"), menuName);
menuElement->GetAttribute(nsAutoString("accesskey"), menuAccessKey);
// Don't create the menu yet, just add in the top level names
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, nsIMenu::GetIID(), (void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pnsMenuBar->QueryInterface(kISupportsIID, (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports);
pnsMenu->SetLabel(menuName);
pnsMenu->SetAccessKey(menuAccessKey);
pnsMenu->SetDOMNode(menuNode);
pnsMenu->SetDOMElement(menuElement);
pnsMenu->SetWebShell(mWebShell);
// Make nsMenu a child of nsMenuBar
// nsMenuBar takes ownership of the nsMenu
pnsMenuBar->AddMenu(pnsMenu);
// Release the menu now that the menubar owns it
NS_RELEASE(pnsMenu);
}
}
}
nsCOMPtr<nsIDOMNode> oldmenuNode(menuNode);
oldmenuNode->GetNextSibling(getter_AddRefs(menuNode));
} // end while (nsnull != menuNode)
// Give the aParentWindow this nsMenuBar to hold onto.
// The parent window should take ownership at this point
aParentWindow->SetMenuBar(pnsMenuBar);
// HACK: force a paint for now
pnsMenuBar->Paint();
NS_RELEASE(pnsMenuBar);
} // end if ( nsnull != pnsMenuBar )
}
return nsEventStatus_eIgnore;
return nsEventStatus_eIgnore;
}
nsEventStatus nsMenuBar::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}

View File

@@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsMenuBar_h__
#define nsMenuBar_h__
#include "nsIMenuBar.h"
#include "nsIMenuListener.h"
#include "nsVoidArray.h"
class nsIDOMNode;
class nsIWebShell;
class nsIWidget;
/**
* Native GTK+ MenuBar wrapper
*/
class nsMenuBar : public nsIMenuBar, public nsIMenuListener
{
public:
nsMenuBar();
virtual ~nsMenuBar();
// nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
NS_DECL_ISUPPORTS
NS_IMETHOD Create(nsIWidget * aParent);
// nsIMenuBar Methods
NS_IMETHOD GetParent(nsIWidget *&aParent);
NS_IMETHOD SetParent(nsIWidget * aParent);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
NS_IMETHOD GetMenuCount(PRUint32 &aCount);
NS_IMETHOD GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
NS_IMETHOD InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
NS_IMETHOD RemoveMenu(const PRUint32 aCount);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void*& aData);
NS_IMETHOD Paint();
NS_IMETHOD SetNativeData(void* aData);
protected:
GtkWidget * mMenuBar;
nsIWidget * mParent;
PRBool mIsMenuBarAdded;
nsIWebShell * mWebShell;
nsIDOMNode * mDOMNode;
nsVoidArray mMenusVoidArray;
PRUint32 mNumMenus;
};
#endif // nsMenuBar_h__

View File

@@ -0,0 +1,539 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsMenuItem.h"
#include "nsIMenu.h"
#include "nsIMenuBar.h"
#include "nsIWidget.h"
#include "nsGtkEventHandler.h"
#include "nsIPopUpMenu.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "nsIContentViewer.h"
#include "nsIDOMElement.h"
#include "nsIDocumentViewer.h"
#include "nsIPresContext.h"
#include "nsIWebShell.h"
#include "nsICharsetConverterManager.h"
#include "nsIPlatformCharset.h"
#include "nsIServiceManager.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
nsresult nsMenuItem::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(nsIMenuItem::GetIID())) {
*aInstancePtr = (void*)(nsIMenuItem*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIMenuItem*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIMenuListener::GetIID())) {
*aInstancePtr = (void*)(nsIMenuListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsMenuItem)
NS_IMPL_RELEASE(nsMenuItem)
//-------------------------------------------------------------------------
//
// nsMenuItem constructor
//
//-------------------------------------------------------------------------
nsMenuItem::nsMenuItem() : nsIMenuItem()
{
NS_INIT_REFCNT();
mMenuItem = nsnull;
mMenuParent = nsnull;
mPopUpParent = nsnull;
mTarget = nsnull;
mXULCommandListener = nsnull;
mIsSeparator = PR_FALSE;
mWebShell = nsnull;
mDOMElement = nsnull;
mIsSubMenu = PR_FALSE;
}
//-------------------------------------------------------------------------
//
// nsMenuItem destructor
//
//-------------------------------------------------------------------------
nsMenuItem::~nsMenuItem()
{
//g_print("nsMenuItem::~nsMenuItem called\n");
//NS_IF_RELEASE(mTarget);
gtk_widget_destroy(mMenuItem);
mMenuItem = nsnull;
//g_print("end nsMenuItem::~nsMenuItem\n");
}
//-------------------------------------------------------------------------
GtkWidget *nsMenuItem::GetNativeParent()
{
void * voidData;
if (nsnull != mMenuParent) {
mMenuParent->GetNativeData(&voidData);
} else if (nsnull != mPopUpParent) {
mPopUpParent->GetNativeData(voidData);
} else {
return nsnull;
}
return GTK_WIDGET(voidData);
}
//-------------------------------------------------------------------------
nsIWidget * nsMenuItem::GetMenuBarParent(nsISupports * aParent)
{
nsIWidget * widget = nsnull; // MenuBar's Parent
nsIMenu * menu = nsnull;
nsIMenuBar * menuBar = nsnull;
nsIPopUpMenu * popup = nsnull;
nsISupports * parent = aParent;
while(1) {
if (NS_OK == parent->QueryInterface(nsIMenu::GetIID(),(void**)&menu)) {
NS_RELEASE(parent);
if (NS_OK != menu->GetParent(parent)) {
NS_RELEASE(menu);
return nsnull;
}
NS_RELEASE(menu);
} else if (NS_OK == parent->QueryInterface(nsIPopUpMenu::GetIID(),(void**)&popup)) {
if (NS_OK != popup->GetParent(widget)) {
widget = nsnull;
}
NS_RELEASE(popup);
NS_RELEASE(parent);
return widget;
} else if (NS_OK == parent->QueryInterface(nsIMenuBar::GetIID(),(void**)&menuBar)) {
if (NS_OK != menuBar->GetParent(widget)) {
widget = nsnull;
}
NS_RELEASE(menuBar);
NS_RELEASE(parent);
return widget;
} else {
NS_RELEASE(parent);
return nsnull;
}
}
return nsnull;
}
GtkWidget*
nsMenuItem::CreateLocalized(const nsString& aLabel)
{
nsresult result;
static nsIUnicodeEncoder* converter = nsnull;
static int isLatin1 = 0;
static int initialized = 0;
if (!initialized) {
initialized = 1;
result = NS_ERROR_FAILURE;
NS_WITH_SERVICE(nsIPlatformCharset, platform, NS_PLATFORMCHARSET_PROGID,
&result);
if (platform && NS_SUCCEEDED(result)) {
nsAutoString charset("");
result = platform->GetCharset(kPlatformCharsetSel_Menu, charset);
if (NS_SUCCEEDED(result) && (charset.Length() > 0)) {
if (!charset.Compare("iso-8859-1", PR_TRUE)) {
isLatin1 = 1;
}
NS_WITH_SERVICE(nsICharsetConverterManager, manager,
NS_CHARSETCONVERTERMANAGER_PROGID, &result);
if (manager && NS_SUCCEEDED(result)) {
result = manager->GetUnicodeEncoder(&charset, &converter);
if (NS_FAILED(result) && converter) {
NS_RELEASE(converter);
converter = nsnull;
}
else if (converter) {
result = converter->SetOutputErrorBehavior(
nsIUnicodeEncoder::kOnError_Replace, nsnull, '?');
}
}
}
}
}
GtkWidget* menuItem = nsnull;
if (converter) {
char labelStr[128];
labelStr[0] = 0;
PRInt32 srcLen = aLabel.Length() + 1;
PRInt32 destLen = sizeof(labelStr);
result = converter->Convert(aLabel.GetUnicode(), &srcLen, labelStr,
&destLen);
if (labelStr[0] && NS_SUCCEEDED(result)) {
menuItem = gtk_menu_item_new_with_label(labelStr);
if (menuItem && (!isLatin1)) {
GtkWidget* label = GTK_BIN(menuItem)->child;
gtk_widget_ensure_style(label);
GtkStyle* style = gtk_style_copy(label->style);
gdk_font_unref(style->font);
style->font = gdk_fontset_load("*");
gtk_widget_set_style(label, style);
gtk_style_unref(style);
}
}
}
else {
char labelStr[128];
aLabel.ToCString(labelStr, sizeof(labelStr));
menuItem = gtk_menu_item_new_with_label(labelStr);
}
return menuItem;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::Create(nsISupports *aParent,
const nsString &aLabel,
PRBool aIsSeparator)
{
if (nsnull == aParent) {
return NS_ERROR_FAILURE;
}
if(aParent) {
nsIMenu * menu;
aParent->QueryInterface(nsIMenu::GetIID(), (void**) &menu);
mMenuParent = menu;
NS_RELEASE(menu);
}
nsIWidget *widget = nsnull; // MenuBar's Parent
nsISupports *sups;
if (NS_OK == aParent->QueryInterface(kISupportsIID,(void**)&sups)) {
widget = GetMenuBarParent(sups);
// GetMenuBarParent will call release for us
// NS_RELEASE(sups);
mTarget = widget;
}
mIsSeparator = aIsSeparator;
mLabel = aLabel;
// create the native menu item
if(mIsSeparator) {
mMenuItem = gtk_menu_item_new();
} else {
mMenuItem = CreateLocalized(aLabel);
}
gtk_widget_show(mMenuItem);
gtk_signal_connect(GTK_OBJECT(mMenuItem), "activate",
GTK_SIGNAL_FUNC(menu_item_activate_handler),
this);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetLabel(nsString &aText)
{
aText = mLabel;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetLabel(nsString &aText)
{
mLabel = aText;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetEnabled(PRBool aIsEnabled)
{
gtk_widget_set_sensitive(GTK_WIDGET(mMenuItem), aIsEnabled);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetEnabled(PRBool *aIsEnabled)
{
*aIsEnabled = GTK_WIDGET_IS_SENSITIVE(mMenuItem);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetChecked(PRBool aIsEnabled)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetChecked(PRBool *aIsEnabled)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetCheckboxType(PRBool aIsCheckbox)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetCheckboxType(PRBool *aIsCheckbox)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetCommand(PRUint32 & aCommand)
{
aCommand = mCommand;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetTarget(nsIWidget *& aTarget)
{
aTarget = mTarget;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetNativeData(void *& aData)
{
aData = (void *)mMenuItem;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::AddMenuListener(nsIMenuListener * aMenuListener)
{
NS_IF_RELEASE(mXULCommandListener);
NS_IF_ADDREF(aMenuListener);
mXULCommandListener = aMenuListener;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::IsSeparator(PRBool & aIsSep)
{
aIsSep = mIsSeparator;
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
if(!mIsSeparator) {
//g_print("nsMenuItem::MenuItemSelected\n");
DoCommand();
}else{
//g_print("nsMenuItem::MenuItemSelected is separator\n");
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuSelected(const nsMenuEvent & aMenuEvent)
{
if(mXULCommandListener)
return mXULCommandListener->MenuSelected(aMenuEvent);
//g_print("nsMenuItem::MenuSelected\n");
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuDeselected(const nsMenuEvent &aMenuEvent)
{
//g_print("nsMenuItem::MenuDeselected\n");
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuConstruct(const nsMenuEvent &aMenuEvent,
nsIWidget *aParentWindow,
void *menuNode,
void *aWebShell)
{
//g_print("nsMenuItem::MenuConstruct\n");
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuDestruct(const nsMenuEvent &aMenuEvent)
{
//g_print("nsMenuItem::MenuDestruct\n");
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
/**
* Sets the JavaScript Command to be invoked when a "gui" event
* occurs on a source widget
* @param aStrCmd the JS command to be cached for later execution
* @return NS_OK
*/
NS_METHOD nsMenuItem::SetCommand(const nsString &aStrCmd)
{
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Executes the "cached" JavaScript Command
* @return NS_OK if the command was executed properly, otherwise an error code
*/
NS_METHOD nsMenuItem::DoCommand()
{
nsresult rv = NS_ERROR_FAILURE;
if(!mWebShell || !mDOMElement)
return rv;
nsCOMPtr<nsIContentViewer> contentViewer;
NS_ENSURE_SUCCESS(mWebShell->GetContentViewer(getter_AddRefs(contentViewer)),
NS_ERROR_FAILURE);
nsCOMPtr<nsIDocumentViewer> docViewer;
docViewer = do_QueryInterface(contentViewer);
if (!docViewer) {
NS_ERROR("Document viewer interface not supported by the content viewer.");
//g_print("Document viewer interface not supported by the content viewer.");
return rv;
}
nsCOMPtr<nsIPresContext> presContext;
if (NS_FAILED(rv = docViewer->GetPresContext(*getter_AddRefs(presContext)))) {
NS_ERROR("Unable to retrieve the doc viewer's presentation context.");
//g_print("Unable to retrieve the doc viewer's presentation context.");
return rv;
}
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event;
event.eventStructType = NS_MOUSE_EVENT;
event.message = NS_MENU_ACTION;
nsCOMPtr<nsIContent> contentNode;
contentNode = do_QueryInterface(mDOMElement);
if (!contentNode) {
NS_ERROR("DOM Node doesn't support the nsIContent interface required to handle DOM events.");
//g_print("DOM Node doesn't support the nsIContent interface required to handle DOM events.");
return rv;
}
rv = contentNode->HandleDOMEvent(*presContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
//g_print("HandleDOMEvent called");
return rv;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetDOMNode(nsIDOMNode * aDOMNode)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetDOMNode(nsIDOMNode ** aDOMNode)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetDOMElement(nsIDOMElement * aDOMElement)
{
mDOMElement = aDOMElement;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetDOMElement(nsIDOMElement ** aDOMElement)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetWebShell(nsIWebShell * aWebShell)
{
mWebShell = aWebShell;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsMenuItem::SetShortcutChar(const nsString &aText)
{
mKeyEquivalent = aText;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsMenuItem::GetShortcutChar(nsString &aText)
{
aText = mKeyEquivalent;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsMenuItem::SetModifiers(PRUint8 aModifiers)
{
mModifiers = aModifiers;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsMenuItem::GetModifiers(PRUint8 * aModifiers)
{
*aModifiers = mModifiers;
return NS_OK;
}

View File

@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsMenuItem_h__
#define nsMenuItem_h__
#include "nsIMenuItem.h"
#include "nsString.h"
#include "nsIMenuListener.h"
class nsIDOMNode;
class nsIDOMElement;
class nsIMenu;
class nsIPopUpMenu;
class nsIWebShell;
class nsIWidget;
/**
* Native GTK+ MenuItem wrapper
*/
class nsMenuItem : public nsIMenuItem, public nsIMenuListener
{
public:
nsMenuItem();
virtual ~nsMenuItem();
// nsISupports
NS_DECL_ISUPPORTS
// nsIMenuItem Methods
NS_IMETHOD Create(nsISupports *aParent,
const nsString &aLabel,
PRBool aIsSeparator);
NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetLabel(nsString &aText);
NS_IMETHOD SetEnabled(PRBool aIsEnabled);
NS_IMETHOD GetEnabled(PRBool *aIsEnabled);
NS_IMETHOD SetChecked(PRBool aIsEnabled);
NS_IMETHOD GetChecked(PRBool *aIsEnabled);
NS_IMETHOD SetCheckboxType(PRBool aIsCheckbox);
NS_IMETHOD GetCheckboxType(PRBool *aIsCheckbox);
NS_IMETHOD GetCommand(PRUint32 & aCommand);
NS_IMETHOD GetTarget(nsIWidget *& aTarget);
NS_IMETHOD GetNativeData(void*& aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD IsSeparator(PRBool & aIsSep);
NS_IMETHOD SetCommand(const nsString & aStrCmd);
NS_IMETHOD DoCommand();
NS_IMETHOD SetDOMNode(nsIDOMNode * aDOMNode);
NS_IMETHOD GetDOMNode(nsIDOMNode ** aDOMNode);
NS_IMETHOD SetDOMElement(nsIDOMElement * aDOMElement);
NS_IMETHOD GetDOMElement(nsIDOMElement ** aDOMElement);
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell);
NS_IMETHOD SetShortcutChar(const nsString &aText);
NS_IMETHOD GetShortcutChar(nsString &aText);
NS_IMETHOD SetModifiers(PRUint8 aModifiers);
NS_IMETHOD GetModifiers(PRUint8 * aModifiers);
// nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
static GtkWidget* CreateLocalized(const nsString& aLabel);
protected:
nsIWidget *GetMenuBarParent(nsISupports * aParentSupports);
GtkWidget *GetNativeParent();
nsIMenuListener *mXULCommandListener;
nsString mLabel;
nsString mKeyEquivalent;
PRUint8 mModifiers;
PRUint32 mCommand;
nsIMenu *mMenuParent;
nsIPopUpMenu *mPopUpParent;
nsIWidget *mTarget;
GtkWidget *mMenuItem; // native cascade widget
PRBool mIsSeparator;
PRBool mIsSubMenu;
nsIWebShell * mWebShell;
nsIDOMElement * mDOMElement;
};
#endif // nsMenuItem_h__

View File

@@ -0,0 +1,214 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsPopUpMenu.h"
#include "nsIMenu.h"
#include "nsIWidget.h"
#include "nsString.h"
#include "nsFileSpec.h" // XXX: For nsAutoCString
NS_IMPL_ISUPPORTS(nsPopUpMenu, nsIPopUpMenu::GetIID())
//-------------------------------------------------------------------------
//
// nsPopUpMenu constructor
//
//-------------------------------------------------------------------------
nsPopUpMenu::nsPopUpMenu() : nsIPopUpMenu()
{
NS_INIT_REFCNT();
mNumMenuItems = 0;
mParent = nsnull;
mMenu = nsnull;
}
//-------------------------------------------------------------------------
//
// nsPopUpMenu destructor
//
//-------------------------------------------------------------------------
nsPopUpMenu::~nsPopUpMenu()
{
NS_IF_RELEASE(mParent);
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::Create(nsIWidget *aParent)
{
mParent = aParent;
NS_ADDREF(mParent);
mMenu = gtk_menu_new();
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::AddItem(const nsString &aText)
{
GtkWidget *widget;
widget = gtk_menu_item_new_with_label ((const char*)nsAutoCString(mLabel));
gtk_widget_show(widget);
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::AddItem(nsIMenuItem * aMenuItem)
{
GtkWidget *widget;
void *voidData;
aMenuItem->GetNativeData(voidData);
widget = GTK_WIDGET(voidData);
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
// XXX add aMenuItem to internal data structor list
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::AddMenu(nsIMenu * aMenu)
{
nsString Label;
GtkWidget *item=NULL, *parentmenu=NULL, *newmenu=NULL;
void *voidData=NULL;
aMenu->GetLabel(Label);
GetNativeData(voidData);
parentmenu = GTK_WIDGET(voidData);
item = gtk_menu_item_new_with_label ((const char*)nsAutoCString(Label));
gtk_widget_show(item);
gtk_menu_shell_append (GTK_MENU_SHELL (parentmenu), item);
voidData = NULL;
aMenu->GetNativeData(&voidData);
newmenu = GTK_WIDGET(voidData);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), newmenu);
// XXX add aMenu to internal data structor list
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::AddSeparator()
{
GtkWidget *widget;
widget = gtk_menu_item_new ();
gtk_widget_show(widget);
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::GetItemCount(PRUint32 &aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::GetItemAt(const PRUint32 aCount, nsIMenuItem *& aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::InsertItemAt(const PRUint32 aCount, nsIMenuItem *& aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::InsertItemAt(const PRUint32 aCount, const nsString & aMenuItemName)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::InsertSeparator(const PRUint32 aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::RemoveItem(const PRUint32 aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::RemoveAll()
{
return NS_OK;
}
//-------------------------------------------------------------------------
void nsPopUpMenu::GetXY(GtkMenu *menu, gint *x, gint *y, gpointer user_data)
{
*x = ((nsPopUpMenu *)(user_data))->mX;
*y = ((nsPopUpMenu *)(user_data))->mY;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::ShowMenu(PRInt32 aX, PRInt32 aY)
{
mX = aX;
mY = aY;
gtk_menu_popup (GTK_MENU(mMenu),
NULL,
NULL,
GetXY,
this,
0,
GDK_CURRENT_TIME);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::GetNativeData(void *& aData)
{
aData = (void *)mMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsPopUpMenu::GetParent(nsIWidget *& aParent)
{
aParent = mParent;
return NS_OK;
}

View File

@@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsPopUpMenu_h__
#define nsPopUpMenu_h__
#include "nsIPopUpMenu.h"
#include <gtk/gtk.h>
class nsIWidget;
/**
* Native GTK+ PopUp wrapper
*/
class nsPopUpMenu : public nsIPopUpMenu
{
public:
nsPopUpMenu();
virtual ~nsPopUpMenu();
NS_DECL_ISUPPORTS
NS_IMETHOD Create(nsIWidget * aParent);
// nsIPopUpMenu Methods
NS_IMETHOD AddItem(const nsString &aText);
NS_IMETHOD AddItem(nsIMenuItem * aMenuItem);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
NS_IMETHOD AddSeparator();
NS_IMETHOD GetItemCount(PRUint32 &aCount);
NS_IMETHOD GetItemAt(const PRUint32 aCount, nsIMenuItem *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aCount, nsIMenuItem *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aCount, const nsString & aMenuItemName);
NS_IMETHOD InsertSeparator(const PRUint32 aCount);
NS_IMETHOD RemoveItem(const PRUint32 aCount);
NS_IMETHOD RemoveAll();
static void GetXY(GtkMenu *menu, gint *x, gint *y, gpointer user_data);
NS_IMETHOD ShowMenu(PRInt32 aX, PRInt32 aY);
NS_IMETHOD GetNativeData(void*& aData);
NS_IMETHOD GetParent(nsIWidget*& aParent);
protected:
nsString mLabel;
PRUint32 mNumMenuItems;
nsIWidget *mParent;
GtkWidget *mMenu;
gint mX;
gint mY;
};
#endif // nsPopUpMenu_h__

View File

@@ -0,0 +1,240 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsRadioButton.h"
#include "nsString.h"
#include "nsGtkEventHandler.h"
NS_IMPL_ADDREF_INHERITED(nsRadioButton, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsRadioButton, nsWidget)
//-------------------------------------------------------------------------
//
// nsRadioButton constructor
//
//-------------------------------------------------------------------------
nsRadioButton::nsRadioButton() : nsWidget(), nsIRadioButton()
{
NS_INIT_REFCNT();
mLabel = nsnull;
mRadioButton = nsnull;
}
//-------------------------------------------------------------------------
//
// nsRadioButton destructor
//
//-------------------------------------------------------------------------
nsRadioButton::~nsRadioButton()
{
#if 0
if (mLabel)
gtk_widget_destroy(mLabel);
#endif
}
//-------------------------------------------------------------------------
//
// Query interface implementation
//
//-------------------------------------------------------------------------
nsresult nsRadioButton::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
nsresult result = nsWidget::QueryInterface(aIID, aInstancePtr);
if (result == NS_NOINTERFACE && aIID.Equals(nsIRadioButton::GetIID())) {
*aInstancePtr = (void*) ((nsIRadioButton*)this);
AddRef();
result = NS_OK;
}
return result;
}
//-------------------------------------------------------------------------
//
// Create the native RadioButton widget
//
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::CreateNative(GtkObject *parentWindow)
{
mWidget = gtk_event_box_new();
mRadioButton = gtk_radio_button_new(nsnull);
gtk_container_add(GTK_CONTAINER(mWidget), mRadioButton);
gtk_widget_show(mRadioButton);
gtk_widget_set_name(mWidget, "nsRadioButton");
gtk_radio_button_set_group(GTK_RADIO_BUTTON(mRadioButton), nsnull);
gtk_signal_connect(GTK_OBJECT(mRadioButton),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
return NS_OK;
}
void
nsRadioButton::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mLabel) {
mLabel = nsnull;
}
else if (aGtkWidget == mRadioButton) {
mRadioButton = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
void nsRadioButton::InitCallbacks(char * aName)
{
InstallButtonPressSignal(mRadioButton);
InstallButtonReleaseSignal(mRadioButton);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_EXPOSURE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
}
//-------------------------------------------------------------------------
//
// Set this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::SetState(const PRBool aState)
{
if (mWidget) {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mRadioButton);
item->active = (gboolean) aState;
gtk_widget_queue_draw(GTK_WIDGET(item));
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set this button state
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::GetState(PRBool& aState)
{
if (mWidget) {
aState = (PRBool) GTK_TOGGLE_BUTTON(mRadioButton)->active;
}
else {
aState = PR_TRUE;
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::SetLabel(const nsString& aText)
{
if (mWidget) {
NS_ALLOC_STR_BUF(label, aText, 256);
g_print("nsRadioButton::SetLabel(%s)\n",label);
if (mLabel) {
gtk_label_set(GTK_LABEL(mLabel), label);
} else {
mLabel = gtk_label_new(label);
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_container_add(GTK_CONTAINER(mRadioButton), mLabel);
gtk_widget_show(mLabel); /* XXX */
gtk_signal_connect(GTK_OBJECT(mLabel),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
NS_FREE_STR_BUF(label);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get this button label
//
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::GetLabel(nsString& aBuffer)
{
aBuffer.Truncate();
if (mWidget) {
if (mLabel) {
char* text;
gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.Append(text);
}
}
return NS_OK;
}
//////////////////////////////////////////////////////////////////////
// SetBackgroundColor for RadioButton
/*virtual*/
void nsRadioButton::SetBackgroundColorNative(GdkColor *aColorNor,
GdkColor *aColorBri,
GdkColor *aColorDark)
{
// use same style copy as SetFont
GtkStyle *style = gtk_style_copy(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0))->style);
style->bg[GTK_STATE_NORMAL]=*aColorNor;
// Mouse over button
style->bg[GTK_STATE_PRELIGHT]=*aColorBri;
// Button is down
style->bg[GTK_STATE_ACTIVE]=*aColorDark;
// other states too? (GTK_STATE_ACTIVE, GTK_STATE_PRELIGHT,
// GTK_STATE_SELECTED, GTK_STATE_INSENSITIVE)
gtk_widget_set_style(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0)), style);
// set style for eventbox too
gtk_widget_set_style(mWidget, style);
gtk_style_unref(style);
}

View File

@@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsRadioButton_h__
#define nsRadioButton_h__
#include "nsWidget.h"
#include "nsIRadioButton.h"
/**
* Native GTK+ Radiobutton wrapper
*/
class nsRadioButton : public nsWidget,
public nsIRadioButton
{
public:
nsRadioButton();
virtual ~nsRadioButton();
// nsISupports
NS_IMETHOD_(nsrefcnt) AddRef();
NS_IMETHOD_(nsrefcnt) Release();
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
// nsIRadioButton part
NS_IMETHOD SetLabel(const nsString& aText);
NS_IMETHOD GetLabel(nsString& aBuffer);
NS_IMETHOD SetState(const PRBool aState);
NS_IMETHOD GetState(PRBool& aState);
virtual PRBool OnMove(PRInt32 aX, PRInt32 aY) { return PR_FALSE; }
virtual PRBool OnPaint(nsPaintEvent & aEvent) { return PR_FALSE; }
virtual PRBool OnResize(nsRect &aRect) { return PR_FALSE; }
// These are needed to Override the auto check behavior
void Armed();
void DisArmed();
protected:
NS_IMETHOD CreateNative(GtkObject *parentWindow);
virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
// Sets background for checkbutton
virtual void SetBackgroundColorNative(GdkColor *aColorNor,
GdkColor *aColorBri,
GdkColor *aColorDark);
GtkWidget *mLabel;
GtkWidget *mRadioButton;
};
#endif // nsRadioButton_h__

View File

@@ -0,0 +1,455 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsScrollbar.h"
#include "nsGUIEvent.h"
#include "nsGtkEventHandler.h"
NS_IMPL_ADDREF_INHERITED(nsScrollbar, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsScrollbar, nsWidget)
NS_IMPL_QUERY_INTERFACE2(nsScrollbar, nsIScrollbar, nsIWidget)
//-------------------------------------------------------------------------
//
// nsScrollbar constructor
//
//-------------------------------------------------------------------------
nsScrollbar::nsScrollbar (PRBool aIsVertical):nsWidget (), nsIScrollbar ()
{
NS_INIT_REFCNT ();
mOrientation = (aIsVertical) ?
GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL;
}
//-------------------------------------------------------------------------
//
// nsScrollbar destructor
//
//-------------------------------------------------------------------------
nsScrollbar::~nsScrollbar ()
{
}
//-------------------------------------------------------------------------
//
// Create the native scrollbar widget
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::CreateNative (GtkObject * parentWindow)
{
// Create scrollbar, random default values
mAdjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 100, 1, 25, 25));
#ifdef USE_SUPERWIN
if (!GDK_IS_SUPERWIN(parentWindow)) {
g_print("Damn, brother. That's not a superwin.\n");
return NS_ERROR_FAILURE;
}
GdkSuperWin *superwin = GDK_SUPERWIN(parentWindow);
mMozBox = gtk_mozbox_new(superwin->bin_window);
#endif /* USE_SUPERWIN */
switch (mOrientation)
{
case GTK_ORIENTATION_HORIZONTAL:
mWidget = gtk_hscrollbar_new (mAdjustment);
break;
case GTK_ORIENTATION_VERTICAL:
mWidget = gtk_vscrollbar_new (mAdjustment);
break;
}
#ifdef USE_SUPERWIN
// make sure that we put the scrollbar into the mozbox
gtk_container_add(GTK_CONTAINER(mMozBox), mWidget);
#endif /* USE_SUPERWIN */
gtk_widget_set_name (mWidget, "nsScrollbar");
gtk_signal_connect (GTK_OBJECT (mAdjustment),
"value_changed",
GTK_SIGNAL_FUNC (handle_scrollbar_value_changed),
this);
gtk_signal_connect (GTK_OBJECT (mAdjustment),
"destroy",
GTK_SIGNAL_FUNC (DestroySignal),
this);
return NS_OK;
}
void
nsScrollbar::OnDestroySignal(GtkWidget* aGtkWidget)
{
if ((void*)aGtkWidget == (void*)mAdjustment) {
mAdjustment = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//-------------------------------------------------------------------------
//
// Define the range settings
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::SetMaxRange (PRUint32 aEndRange)
{
if (mAdjustment) {
GTK_ADJUSTMENT (mAdjustment)->upper = (float) aEndRange;
gtk_signal_emit_by_name (GTK_OBJECT (mAdjustment), "changed");
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Return the range settings
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::GetMaxRange (PRUint32 & aMaxRange)
{
if (mAdjustment)
aMaxRange = (PRUint32) GTK_ADJUSTMENT (mAdjustment)->upper;
else
aMaxRange = 0;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the thumb position
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::SetPosition (PRUint32 aPos)
{
// if (mAdjustment)
// gtk_adjustment_set_value (GTK_ADJUSTMENT (mAdjustment), (float) aPos);
if (mAdjustment && mWidget)
{
//
// The following bit of code borrowed from gtkrange.c,
// gtk_range_adjustment_value_changed():
//
// Ok, so, like, the problem is that the view manager expects
// SetPosition() to simply do that - set the position of the
// scroll bar. Nothing else!
//
// Unfortunately, calling gtk_adjustment_set_value() causes
// the adjustment object (mAdjustment) to emit a
// "value_changed" signal which in turn causes the
// scrollbar widget (mWidget) to scroll to the given position.
//
// The net result of this is that the content is scrolled
// twice, once by the view manager and once by the
// scrollbar - and things get messed up from then onwards.
//
// The following bit of code does the equivalent of
// gtk_adjustment_set_value(), except no signal is emitted.
//
GtkRange * range = GTK_RANGE(mWidget);
GtkAdjustment * adjustment = GTK_ADJUSTMENT(mAdjustment);
adjustment->value = (float) aPos;
if (range->old_value != adjustment->value)
{
gtk_range_slider_update (range);
gtk_range_clear_background (range);
range->old_value = adjustment->value;
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the current thumb position.
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::GetPosition (PRUint32 & aPos)
{
if (mAdjustment)
aPos = (PRUint32) GTK_ADJUSTMENT (mAdjustment)->value;
else
aPos = 0;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the thumb size
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::SetThumbSize (PRUint32 aSize)
{
if (aSize > 0)
{
if (mAdjustment) {
GTK_ADJUSTMENT (mAdjustment)->page_increment = (float) aSize;
GTK_ADJUSTMENT (mAdjustment)->page_size = (float) aSize;
gtk_signal_emit_by_name (GTK_OBJECT (mAdjustment), "changed");
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the thumb size
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::GetThumbSize (PRUint32 & aThumbSize)
{
if (mAdjustment)
aThumbSize = (PRUint32) GTK_ADJUSTMENT (mAdjustment)->page_size;
else
aThumbSize = 0;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the line increment for this scrollbar
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::SetLineIncrement (PRUint32 aLineIncrement)
{
if (aLineIncrement > 0)
{
if (mAdjustment) {
GTK_ADJUSTMENT (mAdjustment)->step_increment = (float) aLineIncrement;
gtk_signal_emit_by_name (GTK_OBJECT (mAdjustment), "changed");
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the line increment for this scrollbar
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::GetLineIncrement (PRUint32 & aLineInc)
{
if (mAdjustment) {
aLineInc = (PRUint32) GTK_ADJUSTMENT (mAdjustment)->step_increment;
}
else
aLineInc = 0;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set all scrolling parameters
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsScrollbar::SetParameters (PRUint32 aMaxRange, PRUint32 aThumbSize,
PRUint32 aPosition, PRUint32 aLineIncrement)
{
if (mAdjustment) {
int thumbSize = (((int) aThumbSize) > 0 ? aThumbSize : 1);
int maxRange = (((int) aMaxRange) > 0 ? aMaxRange : 10);
int mLineIncrement = (((int) aLineIncrement) > 0 ? aLineIncrement : 1);
int maxPos = maxRange - thumbSize;
int pos = ((int) aPosition) > maxPos ? maxPos - 1 : ((int) aPosition);
GTK_ADJUSTMENT (mAdjustment)->lower = 0;
GTK_ADJUSTMENT (mAdjustment)->upper = maxRange;
GTK_ADJUSTMENT (mAdjustment)->page_size = thumbSize;
GTK_ADJUSTMENT (mAdjustment)->page_increment = thumbSize;
GTK_ADJUSTMENT (mAdjustment)->step_increment = mLineIncrement;
// this will emit the changed signal for us
gtk_adjustment_set_value (GTK_ADJUSTMENT (mAdjustment), pos);
}
return NS_OK;
}
//-------------------------------------------------------------------------
int nsScrollbar::AdjustScrollBarPosition (int aPosition)
{
return 0; /* XXX */
}
//-------------------------------------------------------------------------
//
// Deal with scrollbar messages (actually implemented only in nsScrollbar)
//
//-------------------------------------------------------------------------
PRBool nsScrollbar::OnScroll (nsScrollbarEvent & aEvent, PRUint32 cPos)
{
PRBool result = PR_TRUE;
float newPosition;
switch (aEvent.message)
{
// scroll one line right or down
case NS_SCROLLBAR_LINE_NEXT:
{
newPosition = GTK_ADJUSTMENT (mAdjustment)->value;
// newPosition += mLineIncrement;
newPosition += 10;
PRUint32 thumbSize;
PRUint32 maxRange;
GetThumbSize (thumbSize);
GetMaxRange (maxRange);
PRUint32 max = maxRange - thumbSize;
if (newPosition > (int) max)
newPosition = (int) max;
// if an event callback is registered, give it the chance
// to change the increment
if (mEventCallback)
{
aEvent.position = (PRUint32) newPosition;
result = ConvertStatus ((*mEventCallback) (&aEvent));
newPosition = aEvent.position;
}
break;
}
// scroll one line left or up
case NS_SCROLLBAR_LINE_PREV:
{
newPosition = GTK_ADJUSTMENT (mAdjustment)->value;
// newPosition -= mLineIncrement;
newPosition -= 10;
if (newPosition < 0)
newPosition = 0;
// if an event callback is registered, give it the chance
// to change the decrement
if (mEventCallback)
{
aEvent.position = (PRUint32) newPosition;
aEvent.widget = (nsWidget *) this;
result = ConvertStatus ((*mEventCallback) (&aEvent));
newPosition = aEvent.position;
}
break;
}
// Scrolls one page right or down
case NS_SCROLLBAR_PAGE_NEXT:
{
newPosition = GTK_ADJUSTMENT (mAdjustment)->value;
PRUint32 thumbSize;
GetThumbSize (thumbSize);
PRUint32 maxRange;
GetThumbSize (thumbSize);
GetMaxRange (maxRange);
PRUint32 max = maxRange - thumbSize;
if (newPosition > (int) max)
newPosition = (int) max;
// if an event callback is registered, give it the chance
// to change the increment
if (mEventCallback)
{
aEvent.position = (PRUint32) newPosition;
result = ConvertStatus ((*mEventCallback) (&aEvent));
newPosition = aEvent.position;
}
break;
}
// Scrolls one page left or up.
case NS_SCROLLBAR_PAGE_PREV:
{
newPosition = GTK_ADJUSTMENT (mAdjustment)->value;
if (newPosition < 0)
newPosition = 0;
// if an event callback is registered, give it the chance
// to change the increment
if (mEventCallback)
{
aEvent.position = (PRUint32) newPosition;
result = ConvertStatus ((*mEventCallback) (&aEvent));
newPosition = aEvent.position;
}
break;
}
// Scrolls to the absolute position. The current position is specified by
// the cPos parameter.
case NS_SCROLLBAR_POS:
{
newPosition = cPos;
// if an event callback is registered, give it the chance
// to change the increment
if (mEventCallback)
{
aEvent.position = (PRUint32) newPosition;
result = ConvertStatus ((*mEventCallback) (&aEvent));
newPosition = aEvent.position;
}
break;
}
}
/*
GTK_ADJUSTMENT(mAdjustment)->value = newPosition;
gtk_signal_emit_by_name(GTK_OBJECT(mAdjustment), "value_changed");
*/
/*
if (mEventCallback) {
aEvent.position = cPos;
result = ConvertStatus((*mEventCallback)(&aEvent));
newPosition = aEvent.position;
}
*/
return result;
}

View File

@@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsScrollbar_h__
#define nsScrollbar_h__
#include "nsWidget.h"
#include "nsIScrollbar.h"
/**
* Native GTK+ scrollbar wrapper.
*/
class nsScrollbar : public nsWidget,
public nsIScrollbar
{
public:
nsScrollbar(PRBool aIsVertical);
virtual ~nsScrollbar();
NS_DECL_ISUPPORTS_INHERITED
// nsIScrollBar implementation
NS_IMETHOD SetMaxRange(PRUint32 aEndRange);
NS_IMETHOD GetMaxRange(PRUint32& aMaxRange);
NS_IMETHOD SetPosition(PRUint32 aPos);
NS_IMETHOD GetPosition(PRUint32& aPos);
NS_IMETHOD SetThumbSize(PRUint32 aSize);
NS_IMETHOD GetThumbSize(PRUint32& aSize);
NS_IMETHOD SetLineIncrement(PRUint32 aSize);
NS_IMETHOD GetLineIncrement(PRUint32& aSize);
NS_IMETHOD SetParameters(PRUint32 aMaxRange, PRUint32 aThumbSize,
PRUint32 aPosition, PRUint32 aLineIncrement);
virtual PRBool OnScroll (nsScrollbarEvent & aEvent, PRUint32 cPos);
protected:
NS_IMETHOD CreateNative(GtkObject *parentWindow);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
private:
int mOrientation;
GtkAdjustment *mAdjustment;
int AdjustScrollBarPosition(int aPosition);
};
#endif /* nsScrollbar_h__ */

View File

@@ -0,0 +1,125 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nscore.h"
#include "nsIAllocator.h"
#include "plstr.h"
#include "stdio.h"
#include "prlink.h"
#include "nsSound.h"
#include <unistd.h>
#include <gtk/gtk.h>
/* used with esd_open_sound */
//static int esdref = -1;
static PRLibrary *lib = nsnull;
//typedef int (PR_CALLBACK *EsdOpenSoundType)(const char *host);
//typedef int (PR_CALLBACK *EsdCloseType)(int);
/* used to play the sounds from the find symbol call */
typedef int (PR_CALLBACK *EsdPlayFileType)(const char *, const char *, int);
NS_IMPL_ISUPPORTS1(nsSound, nsISound);
////////////////////////////////////////////////////////////////////////
nsSound::nsSound()
{
NS_INIT_REFCNT();
/* we don't need to do esd_open_sound if we are only going to play files
but we will if we want to do things like streams, etc
*/
// EsdOpenSoundType EsdOpenSound;
lib = PR_LoadLibrary("libesd.so");
/*
if (!lib)
return;
EsdOpenSound = (EsdOpenSoundType) PR_FindSymbol(lib, "esd_open_sound");
esdref = (*EsdOpenSound)("localhost");
*/
}
nsSound::~nsSound()
{
/* see above comment */
/*
if (esdref != -1)
{
EsdCloseType EsdClose = (EsdCloseType) PR_FindSymbol(lib, "esd_close");
(*EsdClose)(esdref);
esdref = -1;
}
*/
}
nsresult NS_NewSound(nsISound** aSound)
{
NS_PRECONDITION(aSound != nsnull, "null ptr");
if (! aSound)
return NS_ERROR_NULL_POINTER;
*aSound = new nsSound();
if (! *aSound)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aSound);
return NS_OK;
}
NS_METHOD nsSound::Init(void)
{
return NS_OK;
}
NS_METHOD nsSound::Beep()
{
::gdk_beep();
return NS_OK;
}
NS_METHOD nsSound::Play(nsIFileSpec *filespec)
{
if (lib)
{
char *filename;
filespec->GetNativePath(&filename);
g_print("there are some issues with playing sound right now, but this should work\n");
EsdPlayFileType EsdPlayFile = (EsdPlayFileType) PR_FindSymbol(lib, "esd_play_file");
(*EsdPlayFile)("mozilla", filename, 1);
nsCRT::free(filename);
return NS_OK;
}
return NS_OK;
}

View File

@@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsSound_h__
#define __nsSound_h__
#include "nsISound.h"
#include <gtk/gtk.h>
class nsSound : public nsISound {
public:
nsSound();
virtual ~nsSound();
NS_DECL_ISUPPORTS
NS_DECL_NSISOUND
};
#endif /* __nsSound_h__ */

View File

@@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsTextAreaWidget.h"
#include "nsString.h"
NS_IMPL_ADDREF_INHERITED(nsTextAreaWidget, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsTextAreaWidget, nsWidget)
NS_IMPL_QUERY_INTERFACE2(nsTextAreaWidget, nsITextAreaWidget, nsIWidget)
//-------------------------------------------------------------------------
//
// nsTextAreaWidget constructor
//
//-------------------------------------------------------------------------
nsTextAreaWidget::nsTextAreaWidget()
{
mBackground = NS_RGB(124, 124, 124);
}
//-------------------------------------------------------------------------
//
// nsTextAreaWidget destructor
//
//-------------------------------------------------------------------------
nsTextAreaWidget::~nsTextAreaWidget()
{
gtk_widget_destroy(mTextWidget);
mTextWidget = nsnull;
}
//-------------------------------------------------------------------------
//
// Create the native Text widget
//
//-------------------------------------------------------------------------
NS_METHOD nsTextAreaWidget::CreateNative(GtkObject *parentWindow)
{
PRBool oldIsReadOnly;
mWidget = gtk_scrolled_window_new(nsnull, nsnull);
gtk_container_set_border_width(GTK_CONTAINER(mWidget), 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(mWidget),
GTK_POLICY_NEVER,
GTK_POLICY_ALWAYS);
mTextWidget = gtk_text_new(nsnull, nsnull);
gtk_text_set_word_wrap(GTK_TEXT(mTextWidget), PR_TRUE);
gtk_widget_set_name(mTextWidget, "nsTextAreaWidget");
gtk_widget_show(mTextWidget);
SetPassword(mIsPassword);
SetReadOnly(mIsReadOnly, oldIsReadOnly);
gtk_container_add(GTK_CONTAINER(mWidget), mTextWidget);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// set font for textarea
//
//-------------------------------------------------------------------------
/* virtual */
void nsTextAreaWidget::SetFontNative(GdkFont *aFont)
{
GtkStyle *style = gtk_style_copy(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0))->style);
// gtk_style_copy ups the ref count of the font
gdk_font_unref (style->font);
style->font = aFont;
gdk_font_ref(style->font);
gtk_widget_set_style(GTK_WIDGET (g_list_nth_data(gtk_container_children(GTK_CONTAINER (mWidget)),0)), style);
gtk_style_unref(style);
}

View File

@@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsTextAreaWidget_h__
#define nsTextAreaWidget_h__
#include "nsTextHelper.h"
#include "nsITextAreaWidget.h"
/**
* Native GTK+ multi-line edit control wrapper.
*/
class nsTextAreaWidget : public nsTextHelper
{
public:
nsTextAreaWidget();
virtual ~nsTextAreaWidget();
NS_DECL_ISUPPORTS_INHERITED
virtual void SetFontNative(GdkFont *aFont);
protected:
NS_METHOD CreateNative(GtkObject *parentWindow);
};
#endif // nsTextAreaWidget_h__

View File

@@ -0,0 +1,216 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsTextHelper.h"
#include "nsTextWidget.h"
#include "nsString.h"
NS_IMPL_ADDREF_INHERITED(nsTextHelper, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsTextHelper, nsWidget)
//-------------------------------------------------------------------------
//
// nsTextHelper constructor
//
//-------------------------------------------------------------------------
nsTextHelper::nsTextHelper() : nsWidget(), nsITextAreaWidget(), nsITextWidget()
{
mIsReadOnly = PR_FALSE;
mIsPassword = PR_FALSE;
}
//-------------------------------------------------------------------------
//
// nsTextHelper destructor
//
//-------------------------------------------------------------------------
nsTextHelper::~nsTextHelper()
{
}
//-------------------------------------------------------------------------
//
// Set initial parameters
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::PreCreateWidget(nsWidgetInitData *aInitData)
{
if (nsnull != aInitData) {
nsTextWidgetInitData* data = (nsTextWidgetInitData *) aInitData;
mIsPassword = data->mIsPassword;
mIsReadOnly = data->mIsReadOnly;
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::SetMaxTextLength(PRUint32 aChars)
{
// This is a normal entry only thing, not a text box
gtk_entry_set_max_length(GTK_ENTRY(mTextWidget), (int)aChars);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::GetText(nsString& aTextBuffer, PRUint32 aBufferSize, PRUint32& aActualSize)
{
char *str = nsnull;
if (GTK_IS_ENTRY(mTextWidget))
{
str = gtk_entry_get_text(GTK_ENTRY(mTextWidget));
}
else if (GTK_IS_TEXT(mTextWidget))
{
str = gtk_editable_get_chars (GTK_EDITABLE (mTextWidget), 0,
gtk_text_get_length (GTK_TEXT (mTextWidget)));
}
aTextBuffer.SetLength(0);
aTextBuffer.Append(str);
PRUint32 len = (PRUint32)strlen(str);
aActualSize = len;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::SetText(const nsString& aText, PRUint32& aActualSize)
{
if (GTK_IS_ENTRY(mTextWidget)) {
gtk_entry_set_text(GTK_ENTRY(mTextWidget),
(const gchar *)nsAutoCString(aText));
} else if (GTK_IS_TEXT(mTextWidget)) {
gtk_editable_delete_text(GTK_EDITABLE(mTextWidget), 0,
gtk_text_get_length(GTK_TEXT (mTextWidget)));
gtk_text_insert(GTK_TEXT(mTextWidget),
nsnull, nsnull, nsnull,
(const char *)nsAutoCString(aText),
aText.Length());
}
aActualSize = aText.Length();
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::InsertText(const nsString &aText,
PRUint32 aStartPos,
PRUint32 aEndPos,
PRUint32& aActualSize)
{
gtk_editable_insert_text(GTK_EDITABLE(mTextWidget),
(const gchar *)nsAutoCString(aText),
(gint)aText.Length(), (gint*)&aStartPos);
aActualSize = aText.Length();
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::RemoveText()
{
if (GTK_IS_ENTRY(mTextWidget)) {
gtk_entry_set_text(GTK_ENTRY(mTextWidget), "");
} else if (GTK_IS_TEXT(mTextWidget)) {
gtk_editable_delete_text(GTK_EDITABLE(mTextWidget), 0,
gtk_text_get_length(GTK_TEXT (mTextWidget)));
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::SetPassword(PRBool aIsPassword)
{
mIsPassword = aIsPassword?PR_FALSE:PR_TRUE;
if (GTK_IS_ENTRY(mTextWidget)) {
gtk_entry_set_visibility(GTK_ENTRY(mTextWidget), mIsPassword);
}
// this won't work for gtk_texts
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::SetReadOnly(PRBool aReadOnlyFlag, PRBool& aOldReadOnlyFlag)
{
NS_ASSERTION(nsnull != mTextWidget,
"SetReadOnly - Widget is NULL, Create may not have been called!");
aOldReadOnlyFlag = mIsReadOnly;
mIsReadOnly = aReadOnlyFlag?PR_FALSE:PR_TRUE;
gtk_editable_set_editable(GTK_EDITABLE(mTextWidget), mIsReadOnly);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::SelectAll()
{
nsString text;
PRUint32 actualSize = 0;
PRUint32 numChars = GetText(text, 0, actualSize);
SetSelection(0, numChars);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::SetSelection(PRUint32 aStartSel, PRUint32 aEndSel)
{
gtk_editable_select_region(GTK_EDITABLE(mTextWidget), aStartSel, aEndSel);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel)
{
#if 0
XmTextPosition left;
XmTextPosition right;
if (XmTextGetSelectionPosition(mTextWidget, &left, &right)) {
*aStartSel = (PRUint32)left;
*aEndSel = (PRUint32)right;
} else {
printf("nsTextHelper::GetSelection Error getting positions\n");
return NS_ERROR_FAILURE;
}
#endif
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::SetCaretPosition(PRUint32 aPosition)
{
gtk_editable_set_position(GTK_EDITABLE(mTextWidget), aPosition);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextHelper::GetCaretPosition(PRUint32& aPosition)
{
aPosition = (PRUint32)GTK_EDITABLE(mTextWidget)->current_pos;
return NS_OK;
}

View File

@@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsTextHelper_h__
#define nsTextHelper_h__
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidget.h"
/**
* Base class for nsTextAreaWidget and nsTextWidget
*/
class nsTextHelper : public nsWidget,
public nsITextAreaWidget,
public nsITextWidget
{
public:
nsTextHelper();
virtual ~nsTextHelper();
// nsISupports
NS_IMETHOD_(nsrefcnt) AddRef();
NS_IMETHOD_(nsrefcnt) Release();
NS_IMETHOD SelectAll();
NS_IMETHOD PreCreateWidget(nsWidgetInitData *aInitData);
NS_IMETHOD SetMaxTextLength(PRUint32 aChars);
NS_IMETHOD GetText(nsString& aTextBuffer, PRUint32 aBufferSize, PRUint32& aActualSize);
NS_IMETHOD SetText(const nsString &aText, PRUint32& aActualSize);
NS_IMETHOD InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos, PRUint32& aActualSize);
NS_IMETHOD RemoveText();
NS_IMETHOD SetPassword(PRBool aIsPassword);
NS_IMETHOD SetReadOnly(PRBool aNewReadOnlyFlag, PRBool& aOldReadOnlyFlag);
NS_IMETHOD SetSelection(PRUint32 aStartSel, PRUint32 aEndSel);
NS_IMETHOD GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel);
NS_IMETHOD SetCaretPosition(PRUint32 aPosition);
NS_IMETHOD GetCaretPosition(PRUint32& aPosition);
protected:
GtkWidget *mTextWidget;
PRBool mIsPassword;
PRBool mIsReadOnly;
};
#endif // nsTextHelper_h__

View File

@@ -0,0 +1,130 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsTextWidget.h"
#include "nsString.h"
#include "nsGtkEventHandler.h"
extern int mIsPasswordCallBacksInstalled;
NS_IMPL_ADDREF_INHERITED(nsTextWidget, nsWidget)
NS_IMPL_RELEASE_INHERITED(nsTextWidget, nsWidget)
NS_IMPL_QUERY_INTERFACE2(nsTextWidget, nsITextWidget, nsIWidget)
//-------------------------------------------------------------------------
//
// nsTextWidget constructor
//
//-------------------------------------------------------------------------
nsTextWidget::nsTextWidget() : nsTextHelper()
{
}
//-------------------------------------------------------------------------
//
// nsTextWidget destructor
//
//-------------------------------------------------------------------------
nsTextWidget::~nsTextWidget()
{
// avoid freeing this twice in other destructors
mTextWidget = nsnull;
}
//-------------------------------------------------------------------------
//
// Create the native Entry widget
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsTextWidget::CreateNative(GtkObject *parentWindow)
{
PRBool oldIsReadOnly;
mWidget = gtk_entry_new();
#ifdef USE_SUPERWIN
if (!GDK_IS_SUPERWIN(parentWindow)) {
g_print("Damn, brother. That's not a superwin.\n");
return NS_ERROR_FAILURE;
}
GdkSuperWin *superwin = GDK_SUPERWIN(parentWindow);
mMozBox = gtk_mozbox_new(superwin->bin_window);
#endif /* USE_SUPERWIN */
// used by nsTextHelper because nsTextArea needs a scrolled_window
mTextWidget = mWidget;
gtk_widget_set_name(mWidget, "nsTextWidget");
/*
* GTK's text widget does XIM for us, so we don't want to use the default key handler
* which does XIM, so we connect to a non-XIM key event for the text widget
*/
gtk_signal_connect_after(GTK_OBJECT(mWidget),
"key_press_event",
GTK_SIGNAL_FUNC(handle_key_press_event_for_text),
this);
gtk_signal_connect(GTK_OBJECT(mWidget),
"key_release_event",
GTK_SIGNAL_FUNC(handle_key_release_event_for_text),
this);
SetPassword(mIsPassword);
SetReadOnly(mIsReadOnly, oldIsReadOnly);
gtk_widget_show(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_EXPOSURE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
#ifdef USE_SUPERWIN
// make sure that we put the scrollbar into the mozbox
gtk_container_add(GTK_CONTAINER(mMozBox), mWidget);
#endif /* USE_SUPERWIN */
return NS_OK;
}
PRBool nsTextWidget::OnKey(nsKeyEvent &aEvent)
{
if (mEventCallback) {
return DispatchWindowEvent(&aEvent);
}
return PR_FALSE;
}

View File

@@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsTextWidget_h__
#define nsTextWidget_h__
#include "nsTextHelper.h"
#include "nsITextWidget.h"
/**
* Native GTK+ single line edit control wrapper.
*/
class nsTextWidget : public nsTextHelper
{
public:
nsTextWidget();
virtual ~nsTextWidget();
NS_DECL_ISUPPORTS_INHERITED
PRBool OnKey(nsKeyEvent &aEvent);
protected:
NS_IMETHOD CreateNative(GtkObject *parentWindow);
};
#endif // nsTextWidget_h__

View File

@@ -0,0 +1,144 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nscore.h" // needed for 'nsnull'
#include "nsToolkit.h"
//
// Static thread local storage index of the Toolkit
// object associated with a given thread...
//
static PRUintn gToolkitTLSIndex = 0;
//-------------------------------------------------------------------------
//
// constructor
//
//-------------------------------------------------------------------------
nsToolkit::nsToolkit()
{
NS_INIT_REFCNT();
mSharedGC = nsnull;
}
//-------------------------------------------------------------------------
//
// destructor
//
//-------------------------------------------------------------------------
nsToolkit::~nsToolkit()
{
if (mSharedGC)
gdk_gc_unref(mSharedGC);
// Remove the TLS reference to the toolkit...
PR_SetThreadPrivate(gToolkitTLSIndex, nsnull);
}
//-------------------------------------------------------------------------
//
// nsISupports implementation macro
//
//-------------------------------------------------------------------------
NS_IMPL_ISUPPORTS1(nsToolkit, nsIToolkit)
void nsToolkit::CreateSharedGC(void)
{
GdkPixmap *pixmap;
if (mSharedGC)
return;
pixmap = ::gdk_pixmap_new (NULL, 1, 1, gdk_rgb_get_visual()->depth);
mSharedGC = ::gdk_gc_new (pixmap);
gdk_pixmap_unref (pixmap);
mSharedGC = gdk_gc_ref(mSharedGC);
}
GdkGC *nsToolkit::GetSharedGC(void)
{
return gdk_gc_ref(mSharedGC);
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsToolkit::Init(PRThread *aThread)
{
CreateSharedGC();
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Return the nsIToolkit for the current thread. If a toolkit does not
// yet exist, then one will be created...
//
//-------------------------------------------------------------------------
NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
{
nsIToolkit* toolkit = nsnull;
nsresult rv = NS_OK;
PRStatus status;
// Create the TLS index the first time through...
if (0 == gToolkitTLSIndex) {
status = PR_NewThreadPrivateIndex(&gToolkitTLSIndex, NULL);
if (PR_FAILURE == status) {
rv = NS_ERROR_FAILURE;
}
}
if (NS_SUCCEEDED(rv)) {
toolkit = (nsIToolkit*)PR_GetThreadPrivate(gToolkitTLSIndex);
//
// Create a new toolkit for this thread...
//
if (!toolkit) {
toolkit = new nsToolkit();
if (!toolkit) {
rv = NS_ERROR_OUT_OF_MEMORY;
} else {
NS_ADDREF(toolkit);
toolkit->Init(PR_GetCurrentThread());
//
// The reference stored in the TLS is weak. It is removed in the
// nsToolkit destructor...
//
PR_SetThreadPrivate(gToolkitTLSIndex, (void*)toolkit);
}
} else {
NS_ADDREF(toolkit);
}
*aResult = toolkit;
}
return rv;
}

View File

@@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef TOOLKIT_H
#define TOOLKIT_H
#include "nsIToolkit.h"
#include <gtk/gtk.h>
/**
* Wrapper around the thread running the message pump.
* The toolkit abstraction is necessary because the message pump must
* execute within the same thread that created the widget under Win32.
*/
class nsToolkit : public nsIToolkit
{
public:
nsToolkit();
virtual ~nsToolkit();
NS_DECL_ISUPPORTS
NS_IMETHOD Init(PRThread *aThread);
void CreateSharedGC(void);
GdkGC *GetSharedGC(void);
private:
GdkGC *mSharedGC;
};
#endif // TOOLKIT_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,410 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsWidget_h__
#define nsWidget_h__
#include "nsBaseWidget.h"
#include "nsIRegion.h"
// XXX: This must go away when nsAutoCString moves out of nsFileSpec.h
#include "nsFileSpec.h" // for nsAutoCString()
class nsILookAndFeel;
class nsIAppShell;
class nsIToolkit;
#include <gtk/gtk.h>
#include <gdk/gdkprivate.h>
#include "gtkmozbox.h"
#define USE_SUPERWIN
#define NSRECT_TO_GDKRECT(ns,gdk) \
PR_BEGIN_MACRO \
gdk.x = ns.x; \
gdk.y = ns.y; \
gdk.width = ns.width; \
gdk.height = ns.height; \
PR_END_MACRO
#define NSCOLOR_TO_GDKCOLOR(n,g) \
PR_BEGIN_MACRO \
g.red = 256 * NS_GET_R(n); \
g.green = 256 * NS_GET_G(n); \
g.blue = 256 * NS_GET_B(n); \
PR_END_MACRO
#define NS_TO_GDK_RGB(ns) (ns & 0xff) << 16 | (ns & 0xff00) | ((ns >> 16) & 0xff)
/**
* Base of all GTK+ native widgets.
*/
class nsWidget : public nsBaseWidget
{
public:
nsWidget();
virtual ~nsWidget();
NS_IMETHOD Create(nsIWidget *aParent,
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell = nsnull,
nsIToolkit *aToolkit = nsnull,
nsWidgetInitData *aInitData = nsnull);
NS_IMETHOD Create(nsNativeWidget aParent,
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell = nsnull,
nsIToolkit *aToolkit = nsnull,
nsWidgetInitData *aInitData = nsnull);
NS_IMETHOD Destroy(void);
nsIWidget* GetParent(void);
NS_IMETHOD SetModal(PRBool aModal);
NS_IMETHOD Show(PRBool state);
NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent);
NS_IMETHOD IsVisible(PRBool &aState);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint);
NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth,
PRInt32 aHeight, PRBool aRepaint);
NS_IMETHOD Enable(PRBool aState);
NS_IMETHOD SetFocus(void);
PRBool OnResize(nsSizeEvent event);
virtual PRBool OnResize(nsRect &aRect);
virtual PRBool OnMove(PRInt32 aX, PRInt32 aY);
nsIFontMetrics *GetFont(void);
NS_IMETHOD SetFont(const nsFont &aFont);
NS_IMETHOD SetBackgroundColor(const nscolor &aColor);
NS_IMETHOD SetCursor(nsCursor aCursor);
NS_IMETHOD SetColorMap(nsColorMap *aColorMap);
void* GetNativeData(PRUint32 aDataType);
NS_IMETHOD GetAbsoluteBounds(nsRect &aRect);
NS_IMETHOD WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect);
NS_IMETHOD ScreenToWidget(const nsRect &aOldRect, nsRect &aNewRect);
NS_IMETHOD BeginResizingChildren(void);
NS_IMETHOD EndResizingChildren(void);
NS_IMETHOD GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight);
NS_IMETHOD SetPreferredSize(PRInt32 aWidth, PRInt32 aHeight);
// Use this to set the name of a widget for normal widgets.. not the same as the nsWindow version
NS_IMETHOD SetTitle(const nsString& aTitle);
virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
// the following are nsWindow specific, and just stubbed here
NS_IMETHOD Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect) { return NS_ERROR_FAILURE; }
NS_IMETHOD SetMenuBar(nsIMenuBar *aMenuBar) { return NS_ERROR_FAILURE; }
NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_ERROR_FAILURE; }
// *could* be done on a widget, but that would be silly wouldn't it?
NS_IMETHOD CaptureMouse(PRBool aCapture) { return NS_ERROR_FAILURE; }
NS_IMETHOD Invalidate(PRBool aIsSynchronous);
NS_IMETHOD Invalidate(const nsRect &aRect, PRBool aIsSynchronous);
NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous);
NS_IMETHOD Update(void);
NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
void InitEvent(nsGUIEvent& event, PRUint32 aEventType, nsPoint* aPoint = nsnull);
// Utility functions
void HandleEvent(GdkEvent *event);
PRBool ConvertStatus(nsEventStatus aStatus);
PRBool DispatchMouseEvent(nsMouseEvent& aEvent);
PRBool DispatchStandardEvent(PRUint32 aMsg);
PRBool DispatchFocus(nsGUIEvent &aEvent);
// are we a "top level" widget?
PRBool mIsToplevel;
#ifdef DEBUG
void IndentByDepth(FILE* out);
#endif
// Return the Gdk window used for rendering
virtual GdkWindow * GetRenderWindow(GtkObject * aGtkWidget);
protected:
virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroy();
NS_IMETHOD CreateNative(GtkObject *parentWindow) { return NS_OK; }
nsresult CreateWidget(nsIWidget *aParent,
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData,
nsNativeWidget aNativeParent = nsnull);
PRBool DispatchWindowEvent(nsGUIEvent* event);
// Return the Gdk window whose background should change
virtual GdkWindow *GetWindowForSetBackground();
// Sets font for widgets
virtual void SetFontNative(GdkFont *aFont);
// Sets backround for widgets
virtual void SetBackgroundColorNative(GdkColor *aColorNor,
GdkColor *aColorBri,
GdkColor *aColorDark);
//////////////////////////////////////////////////////////////////
//
// GTK signal installers
//
//////////////////////////////////////////////////////////////////
void InstallMotionNotifySignal(GtkWidget * aWidget);
void InstallDragMotionSignal(GtkWidget * aWidget);
void InstallDragLeaveSignal(GtkWidget * aWidget);
void InstallDragBeginSignal(GtkWidget * aWidget);
void InstallDragDropSignal(GtkWidget * aWidget);
void InstallEnterNotifySignal(GtkWidget * aWidget);
void InstallLeaveNotifySignal(GtkWidget * aWidget);
void InstallButtonPressSignal(GtkWidget * aWidget);
void InstallButtonReleaseSignal(GtkWidget * aWidget);
virtual
void InstallFocusInSignal(GtkWidget * aWidget);
virtual
void InstallFocusOutSignal(GtkWidget * aWidget);
void InstallRealizeSignal(GtkWidget * aWidget);
void AddToEventMask(GtkWidget * aWidget,
gint aEventMask);
//////////////////////////////////////////////////////////////////
//
// OnSomething handlers
//
//////////////////////////////////////////////////////////////////
virtual void OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent);
virtual void OnDragMotionSignal(GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint time);
/* OnDragEnterSignal is not a real signal.. it is only called from OnDragMotionSignal */
virtual void OnDragEnterSignal(GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint time);
virtual void OnDragLeaveSignal(GdkDragContext *context,
guint time);
virtual void OnDragBeginSignal(GdkDragContext *aGdkDragContext);
virtual void OnDragDropSignal(GdkDragContext *aGdkDragContext,
gint x,
gint y,
guint time);
virtual void OnEnterNotifySignal(GdkEventCrossing * aGdkCrossingEvent);
virtual void OnLeaveNotifySignal(GdkEventCrossing * aGdkCrossingEvent);
virtual void OnButtonPressSignal(GdkEventButton * aGdkButtonEvent);
virtual void OnButtonReleaseSignal(GdkEventButton * aGdkButtonEvent);
virtual void OnFocusInSignal(GdkEventFocus * aGdkFocusEvent);
virtual void OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent);
virtual void OnRealize(GtkWidget *aWidget);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
// Static method used to trampoline to OnDestroySignal
static gint DestroySignal(GtkWidget * aGtkWidget,
nsWidget* aWidget);
static void SuppressModality(PRBool aSuppress);
public:
PRBool mIMEEnable;
PRUnichar* mIMECompositionUniString;
PRInt32 mIMECompositionUniStringSize;
void SetXICSpotLocation(nsPoint aPoint);
protected:
//////////////////////////////////////////////////////////////////
//
// GTK widget signals
//
//////////////////////////////////////////////////////////////////
static gint MotionNotifySignal(GtkWidget * aWidget,
GdkEventMotion * aGdkMotionEvent,
gpointer aData);
static gint DragMotionSignal(GtkWidget * aWidget,
GdkDragContext *context,
gint x,
gint y,
guint time,
void *data);
static void DragLeaveSignal(GtkWidget * aWidget,
GdkDragContext *aDragContext,
guint time,
void *aData);
static gint DragBeginSignal(GtkWidget * aWidget,
GdkDragContext *context,
gint x,
gint y,
guint time,
void *data);
static gint DragDropSignal(GtkWidget * aWidget,
GdkDragContext *context,
gint x,
gint y,
guint time,
void *data);
static gint EnterNotifySignal(GtkWidget * aWidget,
GdkEventCrossing * aGdkCrossingEvent,
gpointer aData);
static gint LeaveNotifySignal(GtkWidget * aWidget,
GdkEventCrossing * aGdkCrossingEvent,
gpointer aData);
static gint ButtonPressSignal(GtkWidget * aWidget,
GdkEventButton * aGdkButtonEvent,
gpointer aData);
static gint ButtonReleaseSignal(GtkWidget * aWidget,
GdkEventButton * aGdkButtonEvent,
gpointer aData);
static gint RealizeSignal(GtkWidget * aWidget,
gpointer aData);
static gint FocusInSignal(GtkWidget * aWidget,
GdkEventFocus * aGdkFocusEvent,
gpointer aData);
static gint FocusOutSignal(GtkWidget * aWidget,
GdkEventFocus * aGdkFocusEvent,
gpointer aData);
protected:
//////////////////////////////////////////////////////////////////
//
// GTK event support methods
//
//////////////////////////////////////////////////////////////////
void InstallSignal(GtkWidget * aWidget,
gchar * aSignalName,
GtkSignalFunc aSignalFunction);
PRBool DropEvent(GtkWidget * aWidget,
GdkWindow * aEventWindow);
void InitMouseEvent(GdkEventButton * aGdkButtonEvent,
nsMouseEvent & anEvent,
PRUint32 aEventType);
#ifdef DEBUG
nsCAutoString debug_GetName(GtkObject * aGtkWidget);
nsCAutoString debug_GetName(GtkWidget * aGtkWidget);
PRInt32 debug_GetRenderXID(GtkObject * aGtkWidget);
PRInt32 debug_GetRenderXID(GtkWidget * aGtkWidget);
#endif
guint32 mGrabTime;
GtkWidget *mWidget;
// our mozbox for those native widgets
GtkWidget *mMozBox;
nsIWidget *mParent;
// This is the composite update area (union of all the calls to
// Invalidate)
nsIRegion *mUpdateArea;
PRBool mShown;
PRUint32 mPreferredWidth, mPreferredHeight;
PRBool mListenForResizes;
GdkICPrivate *mIC;
GdkICPrivate *GetXIC();
void SetXIC(GdkICPrivate *aIC);
void GetXYFromPosition(unsigned long *aX, unsigned long *aY);
// this is the rollup listener variables
static nsIRollupListener *gRollupListener;
static nsIWidget *gRollupWidget;
static PRBool gRollupConsumeRollupEvent;
private:
PRBool mIsDragDest;
static nsILookAndFeel *sLookAndFeel;
static PRUint32 sWidgetCount;
//
// Keep track of the last widget being "dragged"
//
static nsWidget *sButtonMotionTarget;
static gint sButtonMotionRootX;
static gint sButtonMotionRootY;
static gint sButtonMotionWidgetX;
static gint sButtonMotionWidgetY;
};
#endif /* nsWidget_h__ */

View File

@@ -0,0 +1,274 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIButton.h"
#include "nsITextWidget.h"
#include "nsWidgetsCID.h"
#include "nsToolkit.h"
#include "nsWindow.h"
#include "nsAppShell.h"
#include "nsButton.h"
#include "nsScrollbar.h"
#include "nsCheckButton.h"
#include "nsRadioButton.h"
#include "nsTextWidget.h"
#include "nsTextAreaWidget.h"
#include "nsFileWidget.h"
#include "nsFileSpecWithUIImpl.h"
#include "nsListBox.h"
#include "nsComboBox.h"
#include "nsLookAndFeel.h"
#include "nsLabel.h"
#ifdef LOSER
#include "nsMenuBar.h"
#include "nsMenu.h"
#include "nsMenuItem.h"
#include "nsPopUpMenu.h"
#include "nsContextMenu.h"
#endif
#include "nsFontRetrieverService.h"
// Drag & Drop, Clipboard
#include "nsClipboard.h"
#include "nsTransferable.h"
#include "nsXIFFormatConverter.h"
#include "nsDragService.h"
#include "nsSound.h"
static NS_DEFINE_IID(kCWindow, NS_WINDOW_CID);
static NS_DEFINE_IID(kCChild, NS_CHILD_CID);
static NS_DEFINE_IID(kCButton, NS_BUTTON_CID);
static NS_DEFINE_IID(kCCheckButton, NS_CHECKBUTTON_CID);
static NS_DEFINE_IID(kCCombobox, NS_COMBOBOX_CID);
static NS_DEFINE_IID(kCFileOpen, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kCListbox, NS_LISTBOX_CID);
static NS_DEFINE_IID(kCRadioButton, NS_RADIOBUTTON_CID);
static NS_DEFINE_IID(kCHorzScrollbar, NS_HORZSCROLLBAR_CID);
static NS_DEFINE_IID(kCVertScrollbar, NS_VERTSCROLLBAR_CID);
static NS_DEFINE_IID(kCTextArea, NS_TEXTAREA_CID);
static NS_DEFINE_IID(kCTextField, NS_TEXTFIELD_CID);
static NS_DEFINE_IID(kCAppShell, NS_APPSHELL_CID);
static NS_DEFINE_IID(kCToolkit, NS_TOOLKIT_CID);
static NS_DEFINE_IID(kCLookAndFeel, NS_LOOKANDFEEL_CID);
static NS_DEFINE_IID(kCLabel, NS_LABEL_CID);
#if 0
static NS_DEFINE_IID(kCMenuBar, NS_MENUBAR_CID);
static NS_DEFINE_IID(kCMenu, NS_MENU_CID);
static NS_DEFINE_IID(kCMenuItem, NS_MENUITEM_CID);
static NS_DEFINE_IID(kCPopUpMenu, NS_POPUPMENU_CID);
static NS_DEFINE_IID(kCContextMenu, NS_CONTEXTMENU_CID);
#endif
static NS_DEFINE_IID(kCFontRetrieverService, NS_FONTRETRIEVERSERVICE_CID);
// Drag & Drop, Clipboard
static NS_DEFINE_IID(kCDataObj, NS_DATAOBJ_CID);
static NS_DEFINE_IID(kCClipboard, NS_CLIPBOARD_CID);
static NS_DEFINE_IID(kCTransferable, NS_TRANSFERABLE_CID);
static NS_DEFINE_IID(kCDataFlavor, NS_DATAFLAVOR_CID);
static NS_DEFINE_IID(kCXIFFormatConverter, NS_XIFFORMATCONVERTER_CID);
static NS_DEFINE_IID(kCDragService, NS_DRAGSERVICE_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
// Sound services (just Beep for now)
static NS_DEFINE_CID(kCSound, NS_SOUND_CID);
static NS_DEFINE_CID(kCFileSpecWithUI, NS_FILESPECWITHUI_CID);
class nsWidgetFactory : public nsIFactory
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIFACTORY
nsWidgetFactory(const nsCID &aClass);
virtual ~nsWidgetFactory();
private:
nsCID mClassID;
};
nsWidgetFactory::nsWidgetFactory(const nsCID &aClass)
{
NS_INIT_ISUPPORTS();
mClassID = aClass;
}
nsWidgetFactory::~nsWidgetFactory()
{
}
NS_IMPL_ISUPPORTS(nsWidgetFactory, NS_GET_IID(nsIFactory))
nsresult nsWidgetFactory::CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
if (aResult == NULL) {
return NS_ERROR_NULL_POINTER;
}
*aResult = NULL;
if (nsnull != aOuter)
return NS_ERROR_NO_AGGREGATION;
nsISupports *inst = nsnull;
if (mClassID.Equals(kCWindow)) {
inst = (nsISupports *)new nsWindow();
}
else if (mClassID.Equals(kCChild)) {
inst = (nsISupports *)new ChildWindow();
}
else if (mClassID.Equals(kCButton)) {
inst = (nsISupports*)(nsWidget *)new nsButton();
}
else if (mClassID.Equals(kCCheckButton)) {
inst = (nsISupports*)(nsWidget *)new nsCheckButton();
}
else if (mClassID.Equals(kCCombobox)) {
inst = (nsISupports*)(nsWidget *)new nsComboBox();
}
else if (mClassID.Equals(kCRadioButton)) {
inst = (nsISupports*)(nsWidget *)new nsRadioButton();
}
else if (mClassID.Equals(kCFileOpen)) {
inst = (nsISupports*)new nsFileWidget();
}
else if (mClassID.Equals(kCListbox)) {
inst = (nsISupports*)(nsWidget *)new nsListBox();
}
else if (mClassID.Equals(kCHorzScrollbar)) {
inst = (nsISupports*)(nsWidget *)new nsScrollbar(PR_FALSE);
}
else if (mClassID.Equals(kCVertScrollbar)) {
inst = (nsISupports*)(nsWidget *)new nsScrollbar(PR_TRUE);
}
else if (mClassID.Equals(kCTextArea)) {
inst = (nsISupports*)(nsWidget *)new nsTextAreaWidget();
}
else if (mClassID.Equals(kCTextField)) {
inst = (nsISupports*)(nsWidget *)new nsTextWidget();
}
else if (mClassID.Equals(kCAppShell)) {
inst = (nsISupports*)new nsAppShell();
}
else if (mClassID.Equals(kCToolkit)) {
inst = (nsISupports*)(nsWidget *)new nsToolkit();
}
else if (mClassID.Equals(kCLookAndFeel)) {
inst = (nsISupports*)(nsWidget *)new nsLookAndFeel();
}
else if (mClassID.Equals(kCLabel)) {
inst = (nsISupports*)(nsWidget *)new nsLabel();
}
#if 0
else if (mClassID.Equals(kCMenuBar)) {
inst = (nsISupports*)(nsIMenuBar *)new nsMenuBar();
}
else if (mClassID.Equals(kCMenu)) {
inst = (nsISupports*)(nsIMenu *)new nsMenu();
}
else if (mClassID.Equals(kCMenuItem)) {
inst = (nsISupports*)(nsIMenuItem *)new nsMenuItem();
}
else if (mClassID.Equals(kCPopUpMenu)) {
inst = (nsISupports*)new nsPopUpMenu();
}
/*
else if (mClassID.Equals(kCContextMenu)) {
inst = (nsISupports*)(nsIContextMenu*)new nsContextMenu();
}
*/
#endif
else if (mClassID.Equals(kCSound)) {
nsISound* aSound = nsnull;
NS_NewSound(&aSound);
inst = (nsISupports*) aSound;
}
else if (mClassID.Equals(kCTransferable)) {
inst = (nsISupports*)new nsTransferable();
}
else if (mClassID.Equals(kCClipboard)) {
inst = (nsISupports*)new nsClipboard();
}
else if (mClassID.Equals(kCXIFFormatConverter))
inst = (nsISupports*)new nsXIFFormatConverter();
else if (mClassID.Equals(kCFontRetrieverService))
inst = (nsISupports*)(nsIFontRetrieverService *) new nsFontRetrieverService();
else if (mClassID.Equals(kCDragService))
inst = (nsISupports*) (nsIDragService *) new nsDragService();
else if (mClassID.Equals(kCFileSpecWithUI))
inst = (nsISupports*) (nsIFileSpecWithUI *) new nsFileSpecWithUIImpl;
else {
printf("nsWidgetFactory::CreateInstance(), unhandled class.\n");
}
if (inst == NULL) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(inst);
nsresult res = inst->QueryInterface(aIID, aResult);
NS_RELEASE(inst);
return res;
}
nsresult nsWidgetFactory::LockFactory(PRBool aLock)
{
// Not implemented in simplest case.
return NS_OK;
}
// return the proper factory to the caller
extern "C" NS_WIDGET nsresult
NSGetFactory(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
if (nsnull == aFactory) {
return NS_ERROR_NULL_POINTER;
}
*aFactory = new nsWidgetFactory(aClass);
if (nsnull == aFactory) {
return NS_ERROR_OUT_OF_MEMORY;
}
return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,211 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsWindow_h__
#define nsWindow_h__
#include "nsISupports.h"
#include "nsWidget.h"
#include "nsString.h"
#include "gtkmozarea.h"
#include "gdksuperwin.h"
class nsFont;
class nsIAppShell;
/**
* Native GTK++ window wrapper.
*/
class nsWindow : public nsWidget
{
public:
// nsIWidget interface
nsWindow();
virtual ~nsWindow();
NS_IMETHOD WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect);
NS_IMETHOD PreCreateWidget(nsWidgetInitData *aWidgetInitData);
virtual void* GetNativeData(PRUint32 aDataType);
NS_IMETHOD Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect);
NS_IMETHOD ScrollRect(nsRect &aSrcRect, PRInt32 aDx, PRInt32 aDy);
NS_IMETHOD SetTitle(const nsString& aTitle);
NS_IMETHOD Show(PRBool aShow);
NS_IMETHOD CaptureMouse(PRBool aCapture);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint);
NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth,
PRInt32 aHeight, PRBool aRepaint);
NS_IMETHOD BeginResizingChildren(void);
NS_IMETHOD EndResizingChildren(void);
NS_IMETHOD Destroy(void);
#ifdef USE_SUPERWIN
NS_IMETHOD GetAbsoluteBounds(nsRect &aRect);
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener,
PRBool aDoCapture,
PRBool aConsumeRollupEvent);
NS_IMETHOD Invalidate(PRBool aIsSynchronous);
NS_IMETHOD Invalidate(const nsRect &aRect, PRBool aIsSynchronous);
NS_IMETHOD SetBackgroundColor(const nscolor &aColor);
NS_IMETHOD SetCursor(nsCursor aCursor);
NS_IMETHOD SetFocus(void);
void QueueDraw();
void UnqueueDraw();
void DoPaint(PRInt32 x, PRInt32 y, PRInt32 width, PRInt32 height,
nsIRegion *aClipRegion);
static gboolean UpdateIdle (gpointer data);
NS_IMETHOD Update(void);
virtual void OnFocusInSignal(GdkEventFocus * aGdkFocusEvent);
virtual void OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent);
virtual void InstallFocusInSignal(GtkWidget * aWidget);
virtual void InstallFocusOutSignal(GtkWidget * aWidget);
#endif /* USE_SUPERWIN */
gint ConvertBorderStyles(nsBorderStyle bs);
// Add an XATOM property to this window.
void StoreProperty(char *property, unsigned char *data);
virtual PRBool IsChild() const;
void SetIsDestroying(PRBool val) {
mIsDestroyingWindow = val;
}
PRBool IsDestroying() const {
return mIsDestroyingWindow;
}
// Utility methods
virtual PRBool OnExpose(nsPaintEvent &event);
virtual PRBool OnDraw(nsPaintEvent &event);
PRBool OnKey(nsKeyEvent &aEvent);
virtual PRBool OnScroll(nsScrollbarEvent & aEvent, PRUint32 cPos);
// in nsWidget now
// virtual PRBool OnResize(nsSizeEvent &aEvent);
static void SuperWinFilter(GdkSuperWin *superwin, XEvent *event, gpointer p);
void HandleXlibExposeEvent(XEvent *event);
void HandleXlibConfigureNotifyEvent(XEvent *event);
void HandleXlibButtonEvent(XButtonEvent *aButtonEvent);
void HandleXlibMotionNotifyEvent(XMotionEvent *aMotionEvent);
void HandleXlibCrossingEvent(XCrossingEvent * aCrossingEvent);
// Return the GtkMozArea that is the nearest parent of this widget
GtkWidget *GetMozArea();
// Return the Gdk window used for rendering
virtual GdkWindow * GetRenderWindow(GtkObject * aGtkWidget);
// XXX Chris - fix these
// virtual void OnButtonPressSignal(GdkEventButton * aGdkButtonEvent);
protected:
//////////////////////////////////////////////////////////////////////
//
// Draw signal
//
//////////////////////////////////////////////////////////////////////
void InitDrawEvent(GdkRectangle * aArea,
nsPaintEvent & aPaintEvent,
PRUint32 aEventType);
void UninitDrawEvent(GdkRectangle * area,
nsPaintEvent & aPaintEvent,
PRUint32 aEventType);
static gint DrawSignal(GtkWidget * aWidget,
GdkRectangle * aArea,
gpointer aData);
virtual gint OnDrawSignal(GdkRectangle * aArea);
virtual void OnRealize(GtkWidget *aWidget);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
//////////////////////////////////////////////////////////////////////
virtual void InitCallbacks(char * aName = nsnull);
NS_IMETHOD CreateNative(GtkObject *parentWidget);
nsIFontMetrics *mFontMetrics;
PRBool mVisible;
PRBool mDisplayed;
PRBool mIsDestroyingWindow;
PRBool mIsTooSmall;
// XXX Temporary, should not be caching the font
nsFont * mFont;
// Resize event management
nsRect mResizeRect;
int mResized;
PRBool mLowerLeft;
GtkWidget *mShell; /* used for toplevel windows */
GdkSuperWin *mSuperWin;
GtkWidget *mMozArea;
GtkWidget *mMozAreaClosestParent;
nsIMenuBar *mMenuBar;
private:
nsresult SetIcon(GdkPixmap *window_pixmap,
GdkBitmap *window_mask);
nsresult SetIcon();
PRBool mIsUpdating;
// this is the current GdkSuperWin with the focus
static nsWindow *focusWindow;
// when this is PR_TRUE we will block focus
// events to prevent recursion
PRBool mBlockFocusEvents;
};
//
// A child window is a window with different style
//
class ChildWindow : public nsWindow {
public:
ChildWindow();
~ChildWindow();
virtual PRBool IsChild() const;
#ifndef USE_SUPERWIN
NS_IMETHOD Destroy(void);
#endif
};
#endif // Window_h__